
/*
 ***************************************************************************
 * MediaTeK Inc.
 * 4F, No. 2 Technology	5th	Rd.
 * Science-based Industrial	Park
 * Hsin-chu, Taiwan, R.O.C.
 *
 * (c) Copyright 2002-2012, MTK.
 *
 * All rights reserved.	MediaTeK's source	code is	an unpublished work	and	the
 * use of a	copyright notice does not imply	otherwise. This	source code
 * contains	confidential trade secret material of MediaTeK Tech. Any attemp
 * or participation	in deciphering,	decoding, reverse engineering or in	any
 * way altering	the	source code	is stricitly prohibited, unless	the	prior
 * written consent of MediaTeK, Inc. is obtained.
 ***************************************************************************

	Module Name:
	9_12_ME_func.c
	
	Abstract:

	Revision History:
	Who			When			What
	--------	----------		----------------------------------------------
	Name		Date			Modification logs
	kenny.weng		2012/8/07	Create
	Andy.Yi		        2012/8/07	add 9.2.1,9.2.2
*/

#include <string.h>
//#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include "omci_adpt_common.h"
#include "omci_adpt_general.h"
#include "omci_lib_internal.h"

#include "libgponmap.h"

#include "mtkswitch_api.h"
#include "blapi_traffic.h"
#include "libcompileoption.h"
#include "libapi_lib_fe.h"
#include "lib_bbf247.h"


enum {
    DOWNSTREAM_GEMPORT,
    UPSTREAM_GEMPORT,
};

#define CONST_DS_TRTCM_NUMBER DOWN_GEMPORT_TO_METER_NUM

uint16_t trtcmChannel[CONST_SHAPING_NUM]={0xFFFF};
uint16_t dsTrtcmTable[CONST_DS_TRTCM_NUMBER] = {0};

static uint8_t dsTrtcmEnableFlag = 0;
extern pthread_mutex_t omciGetAllData;
#if/*TCSUPPORT_COMPILE*/ defined(TCSUPPORT_ALPHION_PON)
int tcontDescriptorArray[32][8] ;
#endif/*TCSUPPORT_COMPILE*/

#define INVALID_TRTCM_CHAN   0xFF



#define INVALID_GEMPORTID 0xFFFF
#define GET_ETH_NO_FROM_PPTP_ETH_UNI_INST(inst) (isFiberhome_551601 ? (inst) : ( (inst) & 0xFF ))

#define GEM_PQ_MAP_ACTION_ADD     0
#define GEM_PQ_MAP_ACTION_DEL     1

#define MAX_GEM_PORT_ONE_TCONT      32
#define QUEUE_MAP_TIMER_MS          6000

#define OLT_CTRL_QOS_PATH            "QoS_Common"
#define OLT_CTRL_QOS                 "OltCtroled"
#define OLT_CTRL_RATE_LIMIT_PATH     "globalstate"
#define OLT_CTRL_RATE_LIMIT          "OltCtrlRateLimit"

typedef struct gem_pq_map_s{
	uint16_t gemId;
	uint8_t pqId;
	uint16_t usQInst;
	uint16_t allocId;
}gem_pq_map_t, *gem_pq_map_ptr;

typedef struct tcont_allocId_map_s{
	uint16_t tcontInst;
	uint16_t allocId;
}tcont_allocId_map_t, *tcont_allocId_map_ptr;

gem_pq_map_t gemPqMap_g[MAX_GEM_PORT_NUM];
tcont_allocId_map_t tcontInfo_g[GPON_TCONT_MAX_NUM];

int setQueueMapTimer = INVALID_TIMERID;

uint8_t tcontidx = 0;

int getPonMacQOSParam(uint16_t allocId,uint8_t *qosChannel, uint8_t *qosType ,uint8_t *ponWeight);
int setPonMacQOSParam(uint8_t qosChannel, uint8_t qosType, uint8_t *ponWeight);


uint16_t findGemPQMapByAllocId(uint16_t allocId, gem_pq_map_ptr gemPqMap)
{
	uint16_t cnt = 0;
	int i = 0;

	if(gemPqMap == NULL)
		return 0;

	for(i=0; i<MAX_GEM_PORT_NUM; i++){
		if(gemPqMap_g[i].allocId == allocId){
			memcpy(&gemPqMap[cnt++],&gemPqMap_g[i],sizeof(gem_pq_map_t));
		}
	}

	return cnt;
}

static int update_queue_mapping_rule(uint16_t *pqMapPtr,uint16_t allocId){
	int i = 0;
	uint8_t newQueue = 0;
	uint16_t gemCnt = 0;
	gem_pq_map_t gemPqMap[MAX_GEM_PORT_ONE_TCONT];
	gponQueueMappingIoctl_t	data={0};
	int ret = 0;

	if(pqMapPtr == NULL)
		return 0;

	memset(gemPqMap,0,sizeof(gemPqMap));
	gemCnt = findGemPQMapByAllocId(allocId,gemPqMap);

	for(i = 0; i<gemCnt; i++)
	{
		newQueue = (uint8_t) (pqMapPtr[gemPqMap[i].usQInst % MAX_NUM_OF_QUEUE_PER_TCONT]);
		if(newQueue != gemPqMap[i].pqId){
			memset(&data, 0, sizeof(gponQueueMappingIoctl_t));
			data.gemPort = gemPqMap[i].gemId;
			ret = getQueueMappingRule(&data);
			if(ret == 0){
				omcidbgPrintf(OMCI_DEBUG_LEVEL_NO_MSG,"[%s] gem=%d, oldQueue=%d, newQueue=%d\n",__FUNCTION__,gemPqMap[i].gemId,data.queue,newQueue);
				data.queue = newQueue;
				recfgQueueMappingRule(&data);
			}
		}
	}

	return 0;
}

static int update_qos_policy_by_tcont(uint16_t tcontInst){

	omci_me_info_t me_info_ts={0};
	omci_me_info_t me_info_pq={0};
	omci_me_info_t me_info_tcont={0};
	omci_priority_queue_ptr pq_ptr=NULL;
	omci_t_cont_ptr tont_ptr=NULL;
	omci_traffic_scheduler_ptr ts_ptr=NULL;
	uint8_t old_ponWeight[MAX_NUM_OF_QUEUE_PER_TCONT] = {0};
	uint8_t ponWeight[MAX_NUM_OF_QUEUE_PER_TCONT] = {0};
	int i = 0, wrrCnt = 0,spCnt = 0;
	uint8_t old_qosType = 0;
	uint8_t qosType = 0;
    uint8_t qosChannel = 0;
	int ret=0;
	uint16_t spQlist[MAX_NUM_OF_QUEUE_PER_TCONT] = {0};
	uint16_t pqMap[MAX_GEM_PORT_ONE_TCONT]={0};
	uint16_t allocId = 0;

	me_info_tcont.class_id = OMCI_CLASS_ID_T_CONT;
	me_info_tcont.inst_id= tcontInst;  //meId is same
	if(omci_attr_get_all_data_except_table_attr(&me_info_tcont) != 0){
		return -1;
	}
	tont_ptr = (omci_t_cont_ptr)(me_info_tcont.attributes);
	allocId = tont_ptr->allocId;

	ret = getPonMacQOSParam(allocId, &qosChannel, &old_qosType, old_ponWeight);
	if(ret != 0)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN,"[%s] getPonMacQOSParam fail!\n",__FUNCTION__);
		return 0;
	}

	memcpy(ponWeight,old_ponWeight,sizeof(ponWeight));
	if(tont_ptr->policy == TCONT_POLICY_SP)
	{
		me_info_ts.class_id = OMCI_CLASS_ID_TRAFFIC_SCHEDULER;
		me_info_ts.inst_id= tcontInst;  //meId is same
		if(omci_attr_get_all_data_except_table_attr(&me_info_ts) == 0){
			ts_ptr = (omci_traffic_scheduler_ptr)(me_info_ts.attributes);
			if(ts_ptr->policy == TCONT_POLICY_WRR){
				for(i = 0; i < MAX_NUM_OF_QUEUE_PER_TCONT; i ++){
					me_info_pq.class_id = OMCI_CLASS_ID_PRIORITY_QUEUE;
					me_info_pq.inst_id = (tcontInst & 0xff00) + (tcontInst & 0x00ff) * MAX_NUM_OF_QUEUE_PER_TCONT + i;  //start meId is same weith tcontId
					if(omci_attr_get_all_data_except_table_attr(&me_info_pq) == 0){
						pq_ptr = (omci_priority_queue_ptr)(me_info_pq.attributes);
						if(pq_ptr->trafficSchedulerPointer == ts_ptr->meId){
							pqMap[i] = wrrCnt;
							ponWeight[wrrCnt] = pq_ptr->weight;
							wrrCnt++;
						}
						else{
							spQlist[spCnt] = i;
							spCnt++;
						}
					}
				}

				//fill in sp Q behind the WRR queue
				if(spCnt != 0){
					for(i = 0; i < spCnt; i ++){
						pqMap[spQlist[i]] = wrrCnt + i;
						ponWeight[wrrCnt + i] = 0;
					}
				}
			}
		}

		omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN,"[%s] wrrCnt=%d,spCnt=%d\n",__FUNCTION__,wrrCnt,spCnt);
		switch(wrrCnt){
			case 0:
			case 1:
				qosType = XMCS_IF_QOS_TYPE_SP;
				break;
			case 2:
				//SPWRR2: q7>q6>q5>q4>q3>q2>q1:q0, q1:q0 = w1:w0
				qosType = XMCS_IF_QOS_TYPE_SPWRR2;
				break;
			case 3:
				qosType = XMCS_IF_QOS_TYPE_SPWRR3;
				break;
			case 4:
				qosType = XMCS_IF_QOS_TYPE_SPWRR4;
				break;
			case 5:
				qosType = XMCS_IF_QOS_TYPE_SPWRR5;
				break;
			case 6:
				qosType = XMCS_IF_QOS_TYPE_SPWRR6;
				break;
			case 7:
				qosType = XMCS_IF_QOS_TYPE_SPWRR7;
				break;
			case 8:
				qosType = XMCS_IF_QOS_TYPE_WRR;
				break;
			default:
				break;
		}

		if(spCnt == 0){
			qosType = XMCS_IF_QOS_TYPE_WRR;
		}
	}

	//update QoS pram
	omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN,"[%s] tcontInst=0x%x, qosChannel=%d, old_qosType=%d, new_qosType=%x\n",
	__FUNCTION__,tcontInst,qosChannel,old_qosType,qosType);

	if(old_qosType != qosType || memcpy(old_ponWeight,ponWeight,sizeof(ponWeight)) != 0){
		ret = setPonMacQOSParam(qosChannel, qosType, ponWeight);
		omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN,"==qosChannel0x=%x,qosType=%d, ponWeight=%d %d %d %d %d %d %d %d; ret=%d\n",
			qosChannel,qosType,ponWeight[7],ponWeight[6],ponWeight[5],ponWeight[4],ponWeight[3],ponWeight[2],ponWeight[1],ponWeight[0],ret);
	}

	if(qosType !=  XMCS_IF_QOS_TYPE_SP && qosType !=  XMCS_IF_QOS_TYPE_WRR){
		//SP+WRR
		update_queue_mapping_rule(pqMap,allocId);
	}

	return 0;
}

int setQueueMapRuleTimeout(void)
{
	int i = 0;
	pthread_mutex_lock(&omciGetAllData);
	setQueueMapTimer = 0;
	//update tcont in use
	for(i=0; i<GPON_TCONT_MAX_NUM; i++){
		if(tcontInfo_g[i].allocId != 0){
			update_qos_policy_by_tcont(tcontInfo_g[i].tcontInst);
		}
	}
	pthread_mutex_unlock(&omciGetAllData);
	return 0;
}

void recordQueueMapInfo(int type, uint16_t gemId, uint8_t pqId,uint16_t usQInst,uint16_t allocId, uint16_t tcontInst){
	int i = 0, j = 0;
	int availableIndex = -1;

	if(type == GEM_PQ_MAP_ACTION_ADD){
		//update gem PQ map
		
		for(i = 0; i < MAX_GEM_PORT_NUM; i++){
			if(gemPqMap_g[i].gemId == gemId){
				availableIndex = i;
				break;
			}else if(gemPqMap_g[i].gemId == 0  && availableIndex == -1){
				availableIndex = i;
			}
		}

		if(availableIndex == -1)
			return;

		gemPqMap_g[availableIndex].gemId = gemId;
		gemPqMap_g[availableIndex].pqId = pqId;
		gemPqMap_g[availableIndex].usQInst = usQInst;
		gemPqMap_g[availableIndex].allocId = allocId;
		
		//update tcont in use
		for(i=0; i<GPON_TCONT_MAX_NUM; i++){
			if(tcontInfo_g[i].allocId == allocId){
				break;
			}
		}

		if(i == GPON_TCONT_MAX_NUM){
			//add allocId & tcontInst
			for(i=0; i<GPON_TCONT_MAX_NUM; i++){
				if(tcontInfo_g[i].allocId == 0){
					tcontInfo_g[i].allocId = allocId;
					tcontInfo_g[i].tcontInst = tcontInst;
					break;
				}
			}
		}
	}
	else if(type == GEM_PQ_MAP_ACTION_DEL){
		//update gem PQ map
		for(i=0; i<MAX_GEM_PORT_NUM; i++){
			if(gemPqMap_g[i].gemId == gemId){
				//remove allocId first
				for(j=0; j<GPON_TCONT_MAX_NUM; j++){
					if(tcontInfo_g[j].allocId == gemPqMap_g[i].allocId){
						tcontInfo_g[j].allocId = 0;
						tcontInfo_g[j].tcontInst = 0;
						break;
					}
				}
				//remove gem queue mapping
				memset(&gemPqMap_g[i],0,sizeof(gemPqMap_g[i]));
				break;
			}
		}
	}

	timerStopS(setQueueMapTimer);
	setQueueMapTimer = timerStartS(QUEUE_MAP_TIMER_MS , (TimerCallback)setQueueMapRuleTimeout, NULL);

	return ;
}
/*******************************************************************************************************************************
9.2.6 GEM Port PM in G.984.4

********************************************************************************************************************************/



/*******************************************************************************************************************************
9.2.1 ANI-G

********************************************************************************************************************************/

static attribute_func_t gemBlockLengthFunc = {
	NULL,
	setGEMBlockLengthValue,
};
static attribute_func_t sfThresholdFunc = {
	NULL,
	setSFThresholdValue,
};

static attribute_func_t sdThresholdFunc = {
	NULL,
	setSDThresholdValue,
};

static attribute_func_t aniGARCFunc = {
	NULL,
	setANIGARCValue,
};

static attribute_func_t opticalSignalLevelFunc = {
	getOpticalSignalLevelValue,
	NULL,
};

static attribute_func_t lowerOpticalThresholdFunc = {
	NULL,
	setLowerOpticalThresholdValue,
};

static attribute_func_t upperOpticalThresholdFunc = {
	NULL,
	setUpperOpticalThresholdValue,
};

static attribute_func_t transmitOpticalLevelFunc = {
	getTransmitOpticalLevelValue,
	NULL,
};

static attribute_func_t lowerTransmitOpticalThresholdFunc = {
	NULL,
	setLowerTransmitOpticalThresholdValue,
};

static attribute_func_t upperTransmitOpticalThresholdFunc = {
	NULL,
	setUpperTransmitOpticalThresholdValue,
};

omci_attr_dscp_t omci_attr_ani_g_op[] = {
{0, 	"meId" , 					2 , ATTR_ACCESS_R,      ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT,&generalAttrFunc},
{1, 	"SR indication" , 			1 , ATTR_ACCESS_R,      ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT,&generalAttrFunc},
{2, 	"Total T-CONT number",  	2 , ATTR_ACCESS_R ,     ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT,&generalAttrFunc},
{3, 	"GEM block length",			2,  ATTR_ACCESS_R_W,    ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT,&gemBlockLengthFunc},
{4, 	"Piggyback DBA report",		1,  ATTR_ACCESS_R,      ATTR_FORMAT_ENUM,            ATTR_FULLY_SUPPORT,&generalAttrFunc},
{5, 	"Deprecated",				1,  ATTR_ACCESS_R,      ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT,&generalAttrFunc},
{6, 	"SF threshold",				1,  ATTR_ACCESS_R_W,    ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT,&sfThresholdFunc},
{7, 	"SD threshold",				1,  ATTR_ACCESS_R_W,    ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT,&sdThresholdFunc},
{8, 	"ARC",						1,  ATTR_ACCESS_R_W,    ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT,&aniGARCFunc},
{9, 	"ARC interval",				1,  ATTR_ACCESS_R_W,    ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT,&generalAttrFunc},
{10, 	"Optical signal level",		2,  ATTR_ACCESS_R,      ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT,&opticalSignalLevelFunc},
{11, 	"Lower optical threshold",	1,  ATTR_ACCESS_R_W,    ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT,&lowerOpticalThresholdFunc},
{12, 	"Upper optical threshold",	1,  ATTR_ACCESS_R_W,    ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT,&upperOpticalThresholdFunc},
{13,	"ONU response time",		2,  ATTR_ACCESS_R,      ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT,&generalAttrFunc},
{14, 	"Transmit optical level",	2,  ATTR_ACCESS_R,      ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT,&transmitOpticalLevelFunc},
{15, 	"Lower transmit optical",	1,  ATTR_ACCESS_R_W,    ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT,&lowerTransmitOpticalThresholdFunc},
{16, 	"Upper transmit optical",	1,  ATTR_ACCESS_R_W,    ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT,&upperTransmitOpticalThresholdFunc},
{255, 	"" , 						0,	0,					0,								0,				NULL}
};

omci_me_func_t omci_me_ani_g_op ={
	omci_me_general_create_op,
	omci_me_general_delete_op,
	omci_me_general_set_op,
	omci_me_general_get_op,
	NULL,
	omci_me_ani_g_test_op,
};

omci_ani_g_t omci_ani_g_attr_data = {0};

omci_attr_t omci_ani_g_attr ={
	(uint8_t *)&omci_ani_g_attr_data,
	sizeof(omci_ani_g_attr_data)
};

/*******************************************************************************************************************************
9.2.2 T-CONT

********************************************************************************************************************************/
static attribute_func_t tcontAllocIdFunc = {
	NULL,
	setTCONTAllocIdValue,
};


static attribute_func_t tcontPolicyFunc = {
	NULL,
	setTCONTPolicyValue,
};

omci_attr_dscp_t omci_attr_t_cont_op[] = {
{0, 	"meId" , 				2,      ATTR_ACCESS_R,          ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT,&generalAttrFunc},
{1, 	"Alloc-ID" , 			2,      ATTR_ACCESS_R_W,        ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT,&tcontAllocIdFunc},
{2, 	"Deprecated", 			1,      ATTR_ACCESS_R ,         ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT,&generalAttrFunc},
{3, 	"Policy",				1,      ATTR_ACCESS_R_W,        ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT,&tcontPolicyFunc},
{255, 	"",						0,	0,	0,	0,		NULL}
};
omci_me_func_t omci_me_t_cont_op ={
	NULL,
	NULL,
	omci_me_general_set_op,
	omci_me_general_get_op,
};

omci_t_cont_t omci_t_cont_attr_data = {0};

omci_attr_t omci_t_cont_attr ={
	(uint8_t *)&omci_t_cont_attr_data,
	sizeof(omci_t_cont_attr_data)
};

/*******************************************************************************************************************************
9.2.3 GEM Port

********************************************************************************************************************************/
static attribute_func_t uniCounterFunc = {
	NULL, //getUNIcounterValue, only get value, implemnt in omci
	NULL,
};

static attribute_func_t encryptionStateFunc = {
	getEncryptionStateValue,
	NULL,
};

static attribute_func_t EncryptionKeyRingFunc = {
    NULL,
    setEncryptionKeyRingValue,
};

omci_attr_dscp_t omci_attr_gem_port_ctp_op[] = {
{0, "meId" , 				2,  ATTR_ACCESS_R_SET_CREATE,       ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{1, "Port-ID" , 			2,  ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{2, "T-CONT pointer", 		2,  ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{3, "Direction", 			1,  ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{4, "TMPointerUp",			2,  ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{5, "TDPointerUp",			2,  ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{6, "UNIcounter",			1,  ATTR_ACCESS_R,                  ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &uniCounterFunc},
{7, "PQPointerDown",		2,  ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{8, "Encryption state",		1,  ATTR_ACCESS_R,                  ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &encryptionStateFunc},
{9, "TDPointerDown",		2,  ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{10, "Encryption key ring",	1,  ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &EncryptionKeyRingFunc},
{255, "", 					0 ,	0 ,0 ,0 , NULL}
};
omci_me_func_t omci_me_gem_port_ctp_op ={
	omci_me_gem_ctp_create_op,
	omci_me_gem_ctp_delete_op,
	omci_me_gem_ctp_set_op, 
	omci_me_general_get_op,
};

omci_gem_port_ctp_t omci_gem_port_ctp_attr_data = {0};

omci_attr_t omci_gem_port_ctp_attr ={
	(uint8_t *)&omci_gem_port_ctp_attr_data,
	sizeof(omci_gem_port_ctp_attr_data)
};

/*******************************************************************************************************************************
9.2.6 GEM Port PM in G.984.4

********************************************************************************************************************************/
omci_attr_dscp_t omci_attr_gem_port_pm_op[] = {
{0, "meId" , 					2 , ATTR_ACCESS_R_SET_CREATE,   ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{1, "Interval end time" , 		1 , ATTR_ACCESS_R,              ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{2, "Threshold data 1/2 id", 	2 , ATTR_ACCESS_R_W_SET_CREATE, ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{3, "Lost packets", 			4 , ATTR_ACCESS_R,              ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{4, "Misinserted packets",		4 , ATTR_ACCESS_R,              ATTR_FORMAT_UNSIGNED_INT,  	 ATTR_FULLY_SUPPORT, &generalAttrFunc},
{5, "Received packets",			5 , ATTR_ACCESS_R,              ATTR_FORMAT_STRING,   		 ATTR_FULLY_SUPPORT, &generalAttrFunc},
{6, "Received blocks",			5 , ATTR_ACCESS_R,              ATTR_FORMAT_STRING,   		 ATTR_FULLY_SUPPORT, &generalAttrFunc},
{7, "Transmitted blocks" ,		5 , ATTR_ACCESS_R,              ATTR_FORMAT_STRING,   		 ATTR_FULLY_SUPPORT, &generalAttrFunc},
{8, "Impaired blocks" ,			4 , ATTR_ACCESS_R,              ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{255, "" ,						0 ,  0 ,0 ,0 ,NULL}
};



int getPortIdByInstIdFromGemPortCtp(uint16_t instanceId, uint16_t *portId)
{
	omci_me_info_t me_info = {0};
	omci_gem_port_ctp_ptr gemport_ctp_me = NULL;

    if(portId == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] port id is NULL.\n",__FUNCTION__,__LINE__);
        return -1;
    }

	me_info.class_id = OMCI_CLASS_ID_GEM_PORT_CTP;
	me_info.inst_id = instanceId;
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d] classID = %d, instId = %x.\n",__FUNCTION__,__LINE__,me_info.class_id ,me_info.inst_id);
	if(omci_attr_get_old_data_except_table_attr(&me_info) != 0){
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]get data failed.\n",__FUNCTION__,__LINE__);
        return -1;
    }  

    gemport_ctp_me = (omci_gem_port_ctp_ptr)me_info.attributes;

    if(gemport_ctp_me == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]GEM PORT CTP is NULL.\n",__FUNCTION__,__LINE__);
        return -1;
    }

	*portId = gemport_ctp_me->portId;

	return 0;
}

uint64_t get64FromHL32(uint32_t high32, uint32_t low32)
{
    uint64_t longVal = 0;
    longVal = high32;
	longVal = (longVal << 32) + low32;
	return longVal;
}

int get_gemport_pm_history_data(pm_history_data_list_ptr pm_list, uint8_t syncFlag)
{
    int ret = 0;
    uint16_t portId = 0;
    GEM_STATISTIC_t gponGemCounter ={0};
    uint64_t longVal = 0;
    uint64_t longVal_prev = 0;

    if(pm_list == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]  pm list is NULL\n",__FUNCTION__,__LINE__);
        return -1;
    }
    ret = getPortIdByInstIdFromGemPortCtp(pm_list->instId, &portId);
	if(ret != 0)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: getPortIdByInstIdFromGemPortCtp fail !\n",__FUNCTION__, __LINE__);
		return -1;
	}

	if(0 != gponmgr_lib_get_gemcounter(portId, &gponGemCounter)) {
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"[%s][%d] :  gponmgr_lib_get_gemcounter fail\n",__FUNCTION__, __LINE__);
		return -1;
	}

    if(syncFlag)
    {
        pm_list->pm_data.gemport_pm.interEndTime= pmIntervalTimes;
    	pm_list->pm_data.gemport_pm.lostPackets = 0;
    	pm_list->pm_data.gemport_pm.misInsertPackets = 0;
    	pm_list->pm_data.gemport_pm.impairedBlocks = 0;
    	
    	longVal = gponGemCounter.rxGemFrame;
    	longVal_prev = pm_list->pm_prev_data.gponGemCnt.rxGemFrame;
    	longVal -= longVal_prev;
    	pm_list->pm_data.gemport_pm.receivedPackets[0] = (longVal >> 32) &0xFF;
    	put32(&pm_list->pm_data.gemport_pm.receivedPackets[1], (uint32_t)(longVal & 0xFFFF));

    	longVal = gponGemCounter.rxGemPayload;
    	longVal_prev = pm_list->pm_prev_data.gponGemCnt.rxGemPayload;
    	longVal -= longVal_prev;
    	longVal /= 48;
    	pm_list->pm_data.gemport_pm.receivedBlocks[0] = (longVal >> 32) &0xFF;
    	put32(&pm_list->pm_data.gemport_pm.receivedBlocks[1], (uint32_t)(longVal & 0xFFFF));

    	longVal = gponGemCounter.txGemPayload;
    	longVal_prev = pm_list->pm_prev_data.gponGemCnt.txGemPayload;
    	longVal -= longVal_prev;
    	longVal /= 48;
    	pm_list->pm_data.gemport_pm.receivedBlocks[0] = (longVal >> 32) &0xFF;
    	put32(&pm_list->pm_data.gemport_pm.receivedBlocks[1], (uint32_t)(longVal & 0xFFFF));

    	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->lostPackets = 0x%x\n",__FUNCTION__,__LINE__, pm_list->pm_data.gemport_pm.lostPackets);
	    omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->misinsertedPackets = 0x%x\n",__FUNCTION__,__LINE__, pm_list->pm_data.gemport_pm.misInsertPackets);
	    omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->receivedPackets format 5bytes = 0x%x%x%x%x%x\n",__FUNCTION__,__LINE__, pm_list->pm_data.gemport_pm.receivedPackets[0], pm_list->pm_data.gemport_pm.receivedPackets[1],
	                                       pm_list->pm_data.gemport_pm.receivedPackets[2], pm_list->pm_data.gemport_pm.receivedPackets[3], pm_list->pm_data.gemport_pm.receivedPackets[4]);
	    omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->receivedBlocks format 5bytes = 0x%x%x%x%x%x\n",__FUNCTION__,__LINE__, pm_list->pm_data.gemport_pm.receivedBlocks[0], pm_list->pm_data.gemport_pm.receivedBlocks[1],
	                                       pm_list->pm_data.gemport_pm.receivedBlocks[2], pm_list->pm_data.gemport_pm.receivedBlocks[3], pm_list->pm_data.gemport_pm.receivedBlocks[4]);
	
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->transmittedBlocks format 5bytes = 0x%x%x%x%x%x\n",__FUNCTION__,__LINE__, pm_list->pm_data.gemport_pm.transBlocks[0], pm_list->pm_data.gemport_pm.transBlocks[1],
	                                       pm_list->pm_data.gemport_pm.transBlocks[2], pm_list->pm_data.gemport_pm.transBlocks[3], pm_list->pm_data.gemport_pm.transBlocks[4]);
	    omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->impairedBlocks = 0x%x\n",__FUNCTION__,__LINE__, pm_list->pm_data.gemport_pm.impairedBlocks);
    }

	memcpy(&pm_list->pm_prev_data.gponGemCnt, &gponGemCounter, sizeof(GEM_STATISTIC_t));

	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->rxGemFrameH rxGemFrameL = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_prev_data.gponGemCnt.rxGemFrame);
    omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->txGemFrameH txGemFrameL = 0x%llx\n",__FUNCTION__,__LINE__,pm_list->pm_prev_data.gponGemCnt.txGemFrame);
    omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->rxGemPayloadH rxGemPayloadL = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_prev_data.gponGemCnt.rxGemPayload);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->txGemPayloadH txGemPayloadL = 0x%llx\n",__FUNCTION__,__LINE__,pm_list->pm_prev_data.gponGemCnt.txGemPayload);
	   
    return 0;
}

int omci_me_gem_port_pm_history_get_curr_op(management_entry_ptr me_entry, omci_me_info_ptr me_info)
{
    int ret = 0;
    uint16_t portId = 0;
    omci_gem_port_pm_ptr gemport_pm_new = NULL;
    GEM_STATISTIC_t gponGemCounter ={0};
    uint64_t longVal = 0;

    if(me_entry == NULL || me_info == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]pointer is NULL.\n",__FUNCTION__,__LINE__);
        return -1;
    }
    gemport_pm_new = (omci_gem_port_pm_ptr)me_info->attributes;

    if(gemport_pm_new == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]me info attribute is NULL.\n",__FUNCTION__,__LINE__);
        return -1;
    }
    
    ret = getPortIdByInstIdFromGemPortCtp(me_info->inst_id, &portId);
	if(ret != 0)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: getPortIdByInstIdFromGemPortCtp fail !\n",__FUNCTION__, __LINE__);
		return -1;
	}

	if(0 != gponmgr_lib_get_gemcounter(portId, &gponGemCounter)) {
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"[%s][%d] :  gponmgr_lib_get_gemcounter fail\n",__FUNCTION__, __LINE__);
		return -1;
	}

	gemport_pm_new->interEndTime = pmIntervalTimes;
	gemport_pm_new->lostPackets = 0;
	gemport_pm_new->misInsertPackets = 0;
	gemport_pm_new->receivedPackets[0] = (uint8_t)(gponGemCounter.rxGemFrame>>32);
	put32(&gemport_pm_new->receivedPackets[1], (uint32_t)gponGemCounter.rxGemFrame);

	longVal = gponGemCounter.rxGemPayload;
	longVal /= 48;
	gemport_pm_new->receivedBlocks[0] = (uint8_t)(longVal>>32);
	put32(&gemport_pm_new->receivedBlocks[1], (uint32_t)(longVal & 0xFFFF));

    longVal = gponGemCounter.txGemPayload;
	longVal /= 48;
	gemport_pm_new->transBlocks[0] = (uint8_t)(longVal>>32);
	put32(&gemport_pm_new->transBlocks[1], (uint32_t)(longVal & 0xFFFF));

	gemport_pm_new->impairedBlocks = 0;

	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->lostPackets = 0x%x\n",__FUNCTION__,__LINE__, gemport_pm_new->lostPackets);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->misinsertedPackets = 0x%x\n",__FUNCTION__,__LINE__, gemport_pm_new->misInsertPackets);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->receivedPackets = 0x%llx\n",__FUNCTION__,__LINE__, gponGemCounter.rxGemFrame);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->receivedPackets format 5bytes = 0x%x%x%x%x%x\n",__FUNCTION__,__LINE__, gemport_pm_new->receivedPackets[0], gemport_pm_new->receivedPackets[1],
	                                       gemport_pm_new->receivedPackets[2], gemport_pm_new->receivedPackets[3], gemport_pm_new->receivedPackets[4]);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->receivedBlocks = 0x%llx\n",__FUNCTION__,__LINE__, gponGemCounter.rxGemPayload);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->receivedBlocks format 5bytes = 0x%x%x%x%x%x\n",__FUNCTION__,__LINE__, gemport_pm_new->receivedBlocks[0], gemport_pm_new->receivedBlocks[1],
	                                       gemport_pm_new->receivedBlocks[2], gemport_pm_new->receivedBlocks[3], gemport_pm_new->receivedBlocks[4]);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->transmittedBlocks = 0x%llx\n",__FUNCTION__,__LINE__,gponGemCounter.txGemPayload);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->transmittedBlocks format 5bytes = 0x%x%x%x%x%x\n",__FUNCTION__,__LINE__, gemport_pm_new->transBlocks[0], gemport_pm_new->transBlocks[1],
	                                       gemport_pm_new->transBlocks[2], gemport_pm_new->transBlocks[3], gemport_pm_new->transBlocks[4]);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->impairedBlocks = 0x%x\n",__FUNCTION__,__LINE__, gemport_pm_new->impairedBlocks);

    return 0;
}

int omci_me_gem_port_pm_history_notify(pm_history_data_list_ptr pm_list, omci_me_info_t threshold_info)
{
    enum{ GEM_PORT_PM_HISTORY_DATA_TCA_NUM = 3};
    omci_threshold_data_1_ptr threshold_data1 = NULL;
    int i = 1;
    uint32_t currentData[GEM_PORT_PM_HISTORY_DATA_TCA_NUM] = {0};
    static uint8_t reportFlag[GEM_PORT_PM_HISTORY_DATA_TCA_NUM] = {0};
    uint8_t alarm_num[GEM_PORT_PM_HISTORY_DATA_TCA_NUM] = {0, 1, 2};
    tca_notify_info_t tca_info = {0};

    if(pm_list == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]  pm_list is NULL fail\n",__FUNCTION__,__LINE__);
        return -1;
    }
    if(omci_pm_is_end_of_interval_time())
    {
        memset(reportFlag, 0, sizeof(reportFlag));
        return 0;
    }
    if(threshold_info.class_id != OMCI_CLASS_ID_THRESHOLD_DATA1){
        return 0;
    }	

	threshold_data1 =  (omci_threshold_data_1_ptr)threshold_info.attributes;
	if(threshold_data1 == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]  threshold value is NULL \n",__FUNCTION__,__LINE__);
        return -1;
    }
    //lost packets(thresholdValue1), misinserted packets(thresholdValue2), impaired blocks(thresholdValue3)
    //because of driver does not implement, the three attribute is 0.    

    for(i = 0; i < GEM_PORT_PM_HISTORY_DATA_TCA_NUM; i++)
    {
        tca_info.classId = pm_list->classId;
        tca_info.instId = pm_list->instId;
        tca_info.currentData = currentData[i];
        tca_info.threshold = threshold_data1->thresholdValue[i];
        tca_info.alarm_num = alarm_num[i];
        tca_info.reportFlag = reportFlag[i];

        reportFlag[i] = omci_pm_report_alarm_by_tca_info(tca_info, 0);
	}

	return 0;
    
}

omci_me_func_t omci_me_gem_port_pm_op ={
	omci_me_general_pm_history_create_del_op,
	omci_me_general_pm_history_create_del_op,
	omci_me_general_pm_history_set_op,
	omci_me_general_pm_history_get_op,
	omci_me_gem_port_pm_history_get_curr_op
};

omci_gem_port_pm_t omci_gem_port_pm_attr_data = {0};

omci_attr_t omci_gem_port_pm_attr ={
	(uint8_t *)&omci_gem_port_pm_attr_data,
	sizeof(omci_gem_port_pm_attr_data)
};

/*******************************************************************************************************************************
9.2.10 Piority queue

********************************************************************************************************************************/
static attribute_func_t maxQueueSizeFunc = {
	getMaxQueueSizeValue,
	NULL,
};

static attribute_func_t allocQueueSizeFunc = {
	getAllocQueueSizeValue,
	setAllocQueueSizeValue,
};

static attribute_func_t relatePortFunc = {
	NULL, //getRelatePortValue, only get value from memory,implement in omci framework
	setRelatePortValue,
};

static attribute_func_t trafficSchedPointFunc = {
	NULL,
	setTrafficSchedPointValue,
};

static attribute_func_t weightGetSetFunc = {
	getWeightValue,
	setWeightValue,
};

static attribute_func_t backPressureOperateFunc = {
	getBackPressureOperatetValue,
	setBackPressureOperatetValue,
};

static attribute_func_t backPressureTimeFunc = {
	getBackPressureTimeValue,
	setBackPressureTimeValue,
};

static attribute_func_t backPressureOccurThredFunc = {
	getBackPressureOccurThredValue,
	setBackPressureOccurThredValue,
};

static attribute_func_t backPressureClearThredFunc = {
	getBackPressureClearThredValue,
	setBackPressureClearThredValue,
};


static attribute_func_t packetDropThredFunc = {
	getPacketDropThredValue,
	setPacketDropThredValue,
};

static attribute_func_t packetDropMax_pFunc = {
	getPacketDropMaxpValue,
	setPacketDropMaxpValue,
};

static attribute_func_t queueDropW_qFunc = {
	getQueueDropWqValue,
	setQueueDropWqValue,
};

static attribute_func_t dropPrecedenceColorMarkFunc = {
	getDropPrecedenceColorMarkValue,
	setDropPrecedenceColorMarkValue,
};

omci_attr_dscp_t omci_attr_priority_queue_op[] = {
{0, "meId" , 							2,  ATTR_ACCESS_R,      ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{1, "Queue cofig option" , 				1,  ATTR_ACCESS_R,      ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{2, "Max queue size", 					2,  ATTR_ACCESS_R,      ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &maxQueueSizeFunc},
{3, "Allocated queue size", 			2,  ATTR_ACCESS_R_W,    ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &allocQueueSizeFunc},
#ifdef TCSUPPORT_PON_ROSTELECOM
{4, "Discard counter reset interval",	2,  ATTR_ACCESS_R_W,    ATTR_FORMAT_UNSIGNED_INT,     ATTR_FULLY_SUPPORT,	&generalAttrFunc},
{5, "Threshold for discarded blocks",	2,  ATTR_ACCESS_R_W,    ATTR_FORMAT_UNSIGNED_INT,     ATTR_FULLY_SUPPORT,	&generalAttrFunc},
#else
{4, "Discard counter reset interval",	2,	ATTR_ACCESS_R_W,    ATTR_FORMAT_UNSIGNED_INT,     ATTR_UNSUPPORT,		NULL},
{5, "Threshold for discarded blocks",	2,	ATTR_ACCESS_R_W,    ATTR_FORMAT_UNSIGNED_INT,     ATTR_UNSUPPORT,		NULL},
#endif
{6, "Related port",						4,  ATTR_ACCESS_R_W,    ATTR_FORMAT_UNSIGNED_INT,     ATTR_FULLY_SUPPORT,	&relatePortFunc},
{7, "Traffic scheduler pointer",		2,  ATTR_ACCESS_R_W,    ATTR_FORMAT_UNSIGNED_INT,     ATTR_FULLY_SUPPORT,	&trafficSchedPointFunc},
{8, "Weight",							1,  ATTR_ACCESS_R_W,    ATTR_FORMAT_UNSIGNED_INT,     ATTR_FULLY_SUPPORT,	&weightGetSetFunc},
{9, "Back pressure operation",			2,  ATTR_ACCESS_R_W,    ATTR_FORMAT_UNSIGNED_INT,     ATTR_FULLY_SUPPORT,	&backPressureOperateFunc},
{10, "Back pressure time",				4,  ATTR_ACCESS_R_W,    ATTR_FORMAT_UNSIGNED_INT,     ATTR_FULLY_SUPPORT,	&backPressureTimeFunc},
{11, "Back pressure occur threshold",	2,  ATTR_ACCESS_R_W,    ATTR_FORMAT_UNSIGNED_INT,     ATTR_FULLY_SUPPORT,	&backPressureOccurThredFunc},
{12, "Back pressure clear threshold",	2,  ATTR_ACCESS_R_W,    ATTR_FORMAT_UNSIGNED_INT,     ATTR_FULLY_SUPPORT,	&backPressureClearThredFunc},
{13, "Packet drop thresholds",			8,  ATTR_ACCESS_R_W,    ATTR_FORMAT_STRING,   		  ATTR_FULLY_SUPPORT,	&packetDropThredFunc},
{14, "Packet drop max_p",				2,  ATTR_ACCESS_R_W,    ATTR_FORMAT_STRING,   		  ATTR_FULLY_SUPPORT,	&packetDropMax_pFunc},
{15, "Queue drop w_q",					1,  ATTR_ACCESS_R_W,    ATTR_FORMAT_UNSIGNED_INT,     ATTR_FULLY_SUPPORT,	&queueDropW_qFunc},
{16, "Drop precedence colour marking",	1,  ATTR_ACCESS_R_W,    ATTR_FORMAT_UNSIGNED_INT,     ATTR_FULLY_SUPPORT,	&dropPrecedenceColorMarkFunc},
{255, "" , 								0 ,	0 ,0 ,0 ,NULL}
};

omci_me_func_t omci_me_priority_queue_op ={
	omci_me_general_create_op,
	omci_me_general_delete_op,
	omci_me_general_set_op,
	omci_me_general_get_op,
};

omci_priority_queue_t omci_priority_queue_attr_data = {0};

omci_attr_t omci_priority_queue_attr ={
	(uint8_t *)&omci_priority_queue_attr_data,
	sizeof(omci_priority_queue_attr_data)
};

/*******************************************************************************************************************************
9.2.11 Traffic Scheduler

********************************************************************************************************************************/
static attribute_func_t tcontPointFunc = {
	NULL,
	setTcontPointValue,
};

static attribute_func_t trafficSchedulerPolicyFunc = {
	NULL,
	setTcontPolicyValue,
};

static attribute_func_t tcontPriorityWeightFunc = {
	NULL,
	NULL,//setTcontPriorityWeightValue, only get value from memory,implement in omci framework
};

omci_attr_dscp_t omci_attr_traffic_scheduler_op[] = {
{0, "meId" , 						2,     ATTR_ACCESS_R,      ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{1, "T-CONT pointer" , 				2,     ATTR_ACCESS_R_W,    ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &tcontPointFunc},
{2, "Traffic Scheduler pointer", 	2,     ATTR_ACCESS_R,      ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{3, "Policy", 						1,     ATTR_ACCESS_R_W,    ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &trafficSchedulerPolicyFunc},
{4, "Priority_Weight",				1,     ATTR_ACCESS_R_W,    ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &tcontPriorityWeightFunc},
{255, "" , 							0 ,  0 ,0 ,0 ,NULL}
};

omci_me_func_t omci_me_traffic_scheduler_op ={
	omci_me_general_create_op,
	omci_me_general_delete_op,
	omci_me_general_set_op,
	omci_me_general_get_op,
};

omci_traffic_scheduler_t omci_traffic_scheduler_attr_data = {0};

omci_attr_t omci_traffic_scheduler_attr ={
	(uint8_t *)&omci_traffic_scheduler_attr_data,
	sizeof(omci_traffic_scheduler_attr_data)
};

/*******************************************************************************************************************************
9.2.12 Traffic Descriptor

********************************************************************************************************************************/


omci_attr_dscp_t omci_attr_traffic_descriptor_op[] = {
{0, "meId" , 					2,     ATTR_ACCESS_R_SET_CREATE,       ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{1, "CIR" , 					4,     ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{2, "PIR", 						4,     ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{3, "CBS", 						4,     ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{4, "PBS",						4,     ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{5, "Colour mode",				1,     ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{6, "Ingress colour marking",	1,     ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{7, "Egress colour marking" ,	1,     ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{8, "Meter type" ,				1,     ATTR_ACCESS_R_SET_CREATE,       ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{255, "" , 						0 ,  0 ,0 ,0 ,NULL}
};

omci_me_func_t omci_me_traffic_descriptor_op ={
	omci_me_general_create_op,
	omci_me_general_delete_op,
	omci_me_traffic_desc_set_op,//omci_me_general_set_op,
	omci_me_general_get_op,
};

omci_traffic_descriptor_t omci_traffic_descriptor_attr_data = {0};

omci_attr_t omci_traffic_descriptor_attr ={
	(uint8_t *)&omci_traffic_descriptor_attr_data,
	sizeof(omci_traffic_descriptor_attr_data)
};

/*******************************************************************************************************************************
9.2.13 GEM port network CTP performance monitoring history data

********************************************************************************************************************************/
omci_attr_dscp_t omci_attr_gemport_net_ctp_pm_his_op[] = {
{0, "meId" , 						2,     ATTR_ACCESS_R_SET_CREATE,           ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{1, "Interval end time" , 			1,     ATTR_ACCESS_R,                      ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{2, "Threshold data 1/2 id", 		2,     ATTR_ACCESS_R_W_SET_CREATE,         ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{3, "Transmitted GEM frames", 		4,     ATTR_ACCESS_R,                      ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT, &generalAttrFunc},
{4, "Received GEM frames",			4,     ATTR_ACCESS_R,                      ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT,	&generalAttrFunc},
{5, "Received payload bytes",		8,     ATTR_ACCESS_R,                      ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT,	&generalAttrFunc},
{6, "Transmitted payload bytes",	8,     ATTR_ACCESS_R,                      ATTR_FORMAT_UNSIGNED_INT,    ATTR_FULLY_SUPPORT,	&generalAttrFunc},
{7, "Encryption key errors" ,		4,     ATTR_ACCESS_R,                      ATTR_FORMAT_UNSIGNED_INT,    ATTR_UNSUPPORT,	NULL},
{255, "" , 							0 , 0 ,0 ,0 ,NULL}
};


int get_gemport_net_ctp_pm_history_data(pm_history_data_list_ptr pm_list, uint8_t syncFlag)
{
    int ret = 0;
    uint16_t portId = 0;
    GEM_STATISTIC_t gponGemCounter ={0};
    uint64_t longVal = 0;
    uint64_t longVal_prev = 0;


    if(pm_list == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]  pm list is NULL\n",__FUNCTION__,__LINE__);
        return -1;
    }
        
    ret = getPortIdByInstIdFromGemPortCtp(pm_list->instId, &portId);
	if(ret != 0)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: getPortIdByInstIdFromGemPortCtp fail !\n",__FUNCTION__, __LINE__);
		return -1;
	}

	if(0 != gponmgr_lib_get_gemcounter(portId, &gponGemCounter)) {
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"[%s][%d] :  gponmgr_lib_get_gemcounter fail\n",__FUNCTION__, __LINE__);
		return -1;
	}

    if(syncFlag)
    {
        pm_list->pm_data.gemport_net_ctp_pm.interEndTime = pmIntervalTimes;
    	pm_list->pm_data.gemport_net_ctp_pm.encrypKeyErr = 0;
    	
    	longVal = gponGemCounter.rxGemFrame;
    	longVal -= longVal_prev;
    	pm_list->pm_data.gemport_net_ctp_pm.receivedGemFrames = (uint32_t)(longVal & 0xFFFF);

    	longVal = gponGemCounter.txGemFrame;
    	longVal -= longVal_prev;
    	pm_list->pm_data.gemport_net_ctp_pm.transGemFrames = (uint32_t)(longVal & 0xFFFF);

    	longVal = gponGemCounter.rxGemPayload;
    	pm_list->pm_data.gemport_net_ctp_pm.receivedPayloadBytes = longVal - longVal_prev;
    	
    	longVal = gponGemCounter.txGemPayload;
    	longVal_prev = pm_list->pm_prev_data.gponGemCnt.txGemPayload;
        pm_list->pm_data.gemport_net_ctp_pm.transPayloadBytes = longVal - longVal_prev;
        
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->encrypKeyErr = 0x%x\n",__FUNCTION__,__LINE__, pm_list->pm_data.gemport_net_ctp_pm.encrypKeyErr);
	    omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->receivedGemFrames = 0x%x\n",__FUNCTION__,__LINE__, pm_list->pm_data.gemport_net_ctp_pm.receivedGemFrames);
	    omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->transGemFrames = 0x%x\n",__FUNCTION__,__LINE__, pm_list->pm_data.gemport_net_ctp_pm.transGemFrames);
	    omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->receivedPayloadBytes = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_data.gemport_net_ctp_pm.receivedPayloadBytes);
	    omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->transPayloadBytes = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_data.gemport_net_ctp_pm.transPayloadBytes);
	    
    }

	memcpy(&pm_list->pm_prev_data.gponGemCnt, &gponGemCounter, sizeof(GEM_STATISTIC_t));

	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->rxGemFrameH rxGemFrameL = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_prev_data.gponGemCnt.rxGemFrame);
    omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->txGemFrameH txGemFrameL = 0x%llx\n",__FUNCTION__,__LINE__,pm_list->pm_prev_data.gponGemCnt.txGemFrame);
    omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->rxGemPayloadH rxGemPayloadL = 0x%llx\n",__FUNCTION__,__LINE__, pm_list->pm_prev_data.gponGemCnt.rxGemPayload);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->txGemPayloadH txGemPayloadL = 0x%llx\n",__FUNCTION__,__LINE__,pm_list->pm_prev_data.gponGemCnt.txGemPayload);
	    
    return 0;
}

int omci_me_gemport_net_ctp_pm_history_get_curr_op(management_entry_ptr me_entry, omci_me_info_ptr me_info)
{
    int ret = 0;
    uint16_t portId = 0;
    omci_gemport_net_ctp_pm_his_ptr gemport_net_ctp_pm_new = NULL;
	GEM_STATISTIC_t gponGemPreData = {0};
    GEM_STATISTIC_t gponGemCounter ={0};

    if(me_entry == NULL || me_info == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]pointer is NULL.\n",__FUNCTION__,__LINE__);
        return -1;
    }
    gemport_net_ctp_pm_new = (omci_gemport_net_ctp_pm_his_ptr)me_info->attributes;

    if(gemport_net_ctp_pm_new == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]me info attribute is NULL.\n",__FUNCTION__,__LINE__);
        return -1;
    }
    
    ret = getPortIdByInstIdFromGemPortCtp(me_info->inst_id, &portId);
	if(ret != 0)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: getPortIdByInstIdFromGemPortCtp fail !\n",__FUNCTION__, __LINE__);
		return -1;
	}

	if(0 != gponmgr_lib_get_gemcounter(portId, &gponGemCounter)) {
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"[%s][%d] :  gponmgr_lib_get_gemcounter fail\n",__FUNCTION__, __LINE__);
		return -1;
	}

	omci_adpt_get_pm_pre_data(me_info->class_id,me_info->inst_id,&gponGemPreData,sizeof(GEM_STATISTIC_t));


	gemport_net_ctp_pm_new->interEndTime = pmIntervalTimes;
	gemport_net_ctp_pm_new->encrypKeyErr = 0;
	gemport_net_ctp_pm_new->transGemFrames = (uint32_t)(gponGemCounter.txGemFrame - gponGemPreData.txGemFrame);
	gemport_net_ctp_pm_new->receivedGemFrames = (uint32_t)(gponGemCounter.rxGemFrame - gponGemPreData.rxGemFrame);
	gemport_net_ctp_pm_new->receivedPayloadBytes = 	gponGemCounter.rxGemPayload - gponGemPreData.rxGemPayload;
	gemport_net_ctp_pm_new->transPayloadBytes = gponGemCounter.txGemPayload	- gponGemPreData.txGemPayload;

	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->txGemFrameH txGemFrameL = 0x%llx\n",__FUNCTION__,__LINE__, gponGemCounter.txGemFrame);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->transGemFrames format 4bytes = 0x%x\n",__FUNCTION__,__LINE__, gemport_net_ctp_pm_new->transGemFrames);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->rxGemFrameH rxGemFrameL = 0x%llx\n",__FUNCTION__,__LINE__, gponGemCounter.rxGemFrame);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->receivedGemFrames format 4bytes = 0x%x\n",__FUNCTION__,__LINE__, gemport_net_ctp_pm_new->receivedGemFrames);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->rxGemPayloadH rxGemPayloadL = 0x%llx\n",__FUNCTION__,__LINE__, gponGemCounter.rxGemPayload);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->receivedPayloadBytes format 8bytes = 0x%llx\n",__FUNCTION__,__LINE__, gemport_net_ctp_pm_new->receivedPayloadBytes);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->txGemPayloadH txGemPayloadL = 0x%llx\n",__FUNCTION__,__LINE__, gponGemCounter.txGemPayload);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->transPayloadBytes format 8bytes = 0x%llx\n",__FUNCTION__,__LINE__, gemport_net_ctp_pm_new->transPayloadBytes);
	
    return 0;
}

int omci_me_gemport_net_ctp_pm_history_notify(pm_history_data_list_ptr pm_list, omci_me_info_t threshold_info)
{
    enum{ GEM_PORT_NET_CTP_PM_HISTORY_DATA_TCA_NUM = 1};
    omci_threshold_data_1_ptr threshold_data1 = NULL;
    int i = 1;
    uint32_t currentData[GEM_PORT_NET_CTP_PM_HISTORY_DATA_TCA_NUM] = {0};
    static uint8_t reportFlag[GEM_PORT_NET_CTP_PM_HISTORY_DATA_TCA_NUM] = {0};
    uint8_t alarm_num[GEM_PORT_NET_CTP_PM_HISTORY_DATA_TCA_NUM] = {1};
    tca_notify_info_t tca_info = {0};    

    if(pm_list == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]  pm_list is NULL fail\n",__FUNCTION__,__LINE__);
        return -1;
    }
    if(omci_pm_is_end_of_interval_time())
    {
        memset(reportFlag, 0, sizeof(reportFlag));
        return 0;
    }
    if(threshold_info.class_id != OMCI_CLASS_ID_THRESHOLD_DATA1){
        return 0;
    }

	threshold_data1 =  (omci_threshold_data_1_ptr)threshold_info.attributes;
	if(threshold_data1 == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]  threshold value is NULL \n",__FUNCTION__,__LINE__);
        return -1;
    }
    //entryption key errors(thresholdValue1)
    //because of driver does not implement, the three attribute is 0.    

    for(i = 0; i < GEM_PORT_NET_CTP_PM_HISTORY_DATA_TCA_NUM; i++)
    {
        tca_info.classId = pm_list->classId;
        tca_info.instId = pm_list->instId;
        tca_info.currentData = currentData[i];
        tca_info.threshold = threshold_data1->thresholdValue[i];
        tca_info.alarm_num = alarm_num[i];
        tca_info.reportFlag = reportFlag[i];

        reportFlag[i] = omci_pm_report_alarm_by_tca_info(tca_info, 0);
	}

	return 0;
    
}


omci_me_func_t omci_me_gemport_net_ctp_pm_his_op ={
	omci_me_general_pm_history_create_del_op,
	omci_me_general_pm_history_create_del_op,
	omci_me_general_pm_history_set_op,
	omci_me_general_pm_history_get_op,
	omci_me_gemport_net_ctp_pm_history_get_curr_op,
};

omci_gemport_net_ctp_pm_his_t omci_gemport_net_ctp_pm_his_attr_data = {0};

omci_attr_t omci_gemport_net_ctp_pm_his_attr ={
	(uint8_t *)&omci_gemport_net_ctp_pm_his_attr_data,
	sizeof(omci_gemport_net_ctp_pm_his_attr_data)
};

/*******************************************************************************************************************************
9.2.14 Energy consumption performance monitoring history data

********************************************************************************************************************************/
#if 0
static attribute_func_t energyComsumPmThrdDataFunc = {
	NULL,
//	setEnergyComsumPmThrdDataValue,
};

static attribute_func_t energyComsumPmDozeTimeFunc = {
//	getEnergyComsumPmTransmitFramesValue,
	NULL,
};

static attribute_func_t energyComsumPmCyclicSleepTimeFunc = {
//	getEnergyComsumPmCyclicSleepTimeValue,
	NULL,
};

static attribute_func_t energyComsumPmEnergyConsumedFunc = {
//	getEnergyComsumPmEnergyConsumedValue,
	NULL,
};
#endif
omci_attr_dscp_t omci_attr_energy_pm_his_op[] = {
{0, "meId" , 					2, ATTR_ACCESS_R_SET_CREATE,       ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT, &generalAttrFunc},
{1, "Interval end time" , 		1, ATTR_ACCESS_R,                  ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT, &generalAttrFunc},
{2, "Threshold data 1/2 id", 	2, ATTR_ACCESS_R_W_SET_CREATE,     ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT, &generalAttrFunc},
{3, "Doze time", 				4, ATTR_ACCESS_R,                  ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT, &generalAttrFunc},
{4, "Cyclic sleep time",		4, ATTR_ACCESS_R,                  ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT,	&generalAttrFunc},
{5, "Energy consumed",			4, ATTR_ACCESS_R,                  ATTR_FORMAT_UNSIGNED_INT,   ATTR_FULLY_SUPPORT,	&generalAttrFunc},
{255, "" , 						0 ,0 ,0 ,0 , NULL}
};

int get_energy_consumed_pm_history_data(pm_history_data_list_ptr pm_list, uint8_t syncFlag)
{
    if(pm_list == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]  pm list is NULL\n",__FUNCTION__,__LINE__);
        return -1;
    }
    if(syncFlag)
    {
        /*driver do not implement energy consumption, so the value is 0*/
        pm_list->pm_data.energy_consumption_pm.interEndTime= pmIntervalTimes;
    	pm_list->pm_data.energy_consumption_pm.dozeTime = 0;
    	pm_list->pm_data.energy_consumption_pm.cyclicSleepTime= 0;
    	pm_list->pm_data.energy_consumption_pm.energyConsumed= 0;
    	
        
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->dozeTime = 0x%x\n",__FUNCTION__,__LINE__, pm_list->pm_data.energy_consumption_pm.dozeTime);
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->cyclicSleepTime = 0x%x\n",__FUNCTION__,__LINE__, pm_list->pm_data.energy_consumption_pm.cyclicSleepTime);
    	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]15min->energyConsumed = 0x%x\n",__FUNCTION__,__LINE__, pm_list->pm_data.energy_consumption_pm.energyConsumed);
    }
	    
    return 0;
}

int omci_me_energy_consumed_pm_history_get_curr_op(management_entry_ptr me_entry, omci_me_info_ptr me_info)
{
    omci_energy_consumption_pm_his_ptr energy_con = NULL;

    if(me_entry == NULL || me_info == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]pointer is NULL.\n",__FUNCTION__,__LINE__);
        return -1;
    }
    energy_con = (omci_energy_consumption_pm_his_ptr)me_info->attributes;

    if(energy_con == NULL)
    {
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]me info attribute is NULL.\n",__FUNCTION__,__LINE__);
        return -1;
    }
    /*driver do not implement energy consumption, so the value is 0*/
	energy_con->interEndTime= pmIntervalTimes;
	energy_con->dozeTime= 0;
	energy_con->cyclicSleepTime= 0;
	energy_con->energyConsumed= 0;
	
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->dozeTime = 0x%x\n",__FUNCTION__,__LINE__, energy_con->dozeTime);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->cyclicSleepTime = 0x%x\n",__FUNCTION__,__LINE__, energy_con->dozeTime);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_DEBUG,"[%s][%d]->energyConsumed = 0x%x\n",__FUNCTION__,__LINE__, energy_con->energyConsumed);
	
    return 0;
}


omci_me_func_t omci_me_energy_pm_his_op ={
	omci_me_general_pm_history_create_del_op,
	omci_me_general_pm_history_create_del_op,
	omci_me_general_pm_history_set_op,
	omci_me_general_pm_history_get_op,
	omci_me_energy_consumed_pm_history_get_curr_op,
};

omci_energy_consumption_pm_his_t omci_energy_pm_his_attr_data = {0};

omci_attr_t omci_energy_pm_his_attr ={
	(uint8_t *)&omci_energy_pm_his_attr_data,
	sizeof(omci_energy_pm_his_attr_data)
};



/*****************************************************************************/
static int setPonMacTrafficDescriptor(uint8_t portId, trafficDescriptor_t *trafficDescriptor)
{
	struct XMCS_TxQueueTrtcm_S wanTrtcmParameters;
	
	wanTrtcmParameters.tsIdx = portId ;
	wanTrtcmParameters.cirValue = trafficDescriptor->CIR ;
	wanTrtcmParameters.cbsUnit = trafficDescriptor->CBS ;
	wanTrtcmParameters.pirValue = trafficDescriptor->PIR ;
	wanTrtcmParameters.pbsUnit = trafficDescriptor->PBS ;
	return gponmgr_lib_set_trtcm_para(&wanTrtcmParameters);
}

/*******************************************************************************************************************************

9.2.12 traffic descriptor  API  (Kenny)

********************************************************************************************************************************/
/*******************************************************************************************
**function name
	setBoundTD
**description:
	set Bound traffic descriptor to limit the trafic
 **retrun :
 	-1:	failure
 	0: 	success
**parameter:
  	portId: lan port id or wan port id
  	ifcType: 0:lan interface, 1: wan interface
  	tdInstId: 9.2.12 traffic descriptor instance id
  	dir: 1:in bound  0:out bound
********************************************************************************************/
int setBoundTD(IN uint8_t portId, IN uint8_t ifcType, IN uint16_t tdInstId, IN uint8_t dir){
	int ret = 0;
	trafficDescriptor_t trafficDescriptor;
	omci_me_info_t me_info = {0};
	omci_traffic_descriptor_ptr traffic_desp_attr = NULL;
	
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"Enter %s [%d]\n",__FUNCTION__,__LINE__);
	memset(&trafficDescriptor, 0, sizeof(trafficDescriptor_t));
	
	me_info.class_id = OMCI_CLASS_ID_TRAFFIC_DESCRIPTOR;
	me_info.inst_id = tdInstId;
	if(omci_attr_get_all_data_except_table_attr(&me_info) != 0){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]omci_attr_get_all_data_except_table_attr failed.\n",__FUNCTION__,__LINE__);
		ret = -1;
		goto end;
	}
	traffic_desp_attr = (omci_traffic_descriptor_ptr)me_info.attributes;
	if(NULL == traffic_desp_attr){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "%s->traffic_desp_attr calloc fail\n",__FUNCTION__);
		ret = -1;
		goto end;
	}
	if(traffic_desp_attr->pir == 0)
	{
	    omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "[%s][%d] traffic descriptor PIR = 0, use factory PIR config(not speed limit)\n",__FUNCTION__, __LINE__);
	    return 0;
	}
	trafficDescriptor.CIR = traffic_desp_attr->cir;
	trafficDescriptor.PIR = traffic_desp_attr->pir;
	trafficDescriptor.CBS = traffic_desp_attr->cbs;
	trafficDescriptor.PBS = traffic_desp_attr->pbs;
	trafficDescriptor.colourMode= traffic_desp_attr->colourMode;
	trafficDescriptor.ingressColourMarking= traffic_desp_attr->ingressColourMode;
	trafficDescriptor.engressColourMarking= traffic_desp_attr->egressColourMode;
	trafficDescriptor.meterType= traffic_desp_attr->meterType;
	
	trafficDescriptor.direction = dir;//1:RX  0:TX

	if(trafficDescriptor.CIR == 0 && trafficDescriptor.PIR != 0)
	    trafficDescriptor.CIR = trafficDescriptor.PIR;
	portId--;
	if(ifcType == 0)
	{
#if/*TCSUPPORT_COMPILE*/ defined(TCSUPPORT_ALPHION_PON)
		if(portId != 6)
		{
#endif/*TCSUPPORT_COMPILE*/
		ret = macMT7530SetTrafficDescriptor(portId, (mt7530_switch_api_trafficDescriptor_t *)(&trafficDescriptor));
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setInBoundTD: macMT7530SetTrafficDescriptor fail!\n");
			goto end;
		}
#if/*TCSUPPORT_COMPILE*/ defined(TCSUPPORT_ALPHION_PON)
		}
#endif/*TCSUPPORT_COMPILE*/
	}
	else
	{
		//wait for PON API	,still some problem
		ret = setPonMacTrafficDescriptor(portId, &trafficDescriptor);
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setInBoundTD: setPonMacTrafficDescriptor fail!\n");
			goto end;
		}		
	}
	ret = 0;
end:
	return ret;
}

int cleanBoundTD(IN uint8_t portId, IN uint8_t ifcType, IN uint8_t tdInstId, IN uint8_t dir){
	int ret = 0;
	
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"Enter %s [%d]\n",__FUNCTION__,__LINE__);

	if(ifcType == 0)
	{
		portId--;
		ret = macMT7530CleanTrafficDescriptor(portId, dir);
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"%s [%d]: macMT7530CleanTrafficDescriptor fail!\n",__FUNCTION__,__LINE__);
			return ret;	
		}
	}
	else
	{
		//wait for PON API
	}
	
	return ret;
}

int omciEmptyQueueMappingRule(void)
{
	int ret = 0;
	gponQueueMappingIoctl_t data;

    omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "[%s][%d]Enter\n", __FUNCTION__, __LINE__);
/*gpon queue map api*/
	memset(&data, 0, sizeof(gponQueueMappingIoctl_t));
	data.gemPort = EMPTY_GPONMAP_RULE;

	recordQueueMapInfo(GEM_PQ_MAP_ACTION_DEL,data.gemPort,0,0,0,0); //only need gemPort while delete
	ret = delQueueMappingRule(&data);
	if (ret == GPONMAP_ENTRY_NOT_FOUND)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "omciEmptyQueueMappingRule:GPONMAP_ENTRY_NOT_FOUND\n");
	}
	else if (ret == GPONMAP_SUCCESS)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "omciEmptyQueueMappingRule: delete old queue mapping rule\n");		
	}
	else if (ret == GPONMAP_FAIL)
	{	
		omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "omciEmptyQueueMappingRule: delete queue mapping rule fail\n");		
		goto fail;
	}

	clearOmciGemportRule();
	clearOmciMBInfo();
	gpon_ani_map_clean();
	//Init Gpon Mapping Trtcm
	memset(trtcmChannel, 0xff, sizeof(trtcmChannel));
#if defined(TCSUPPORT_ALPHION_PON)
	//Init Tcont Descriptor
	memset(tcontDescriptorArray,0,sizeof(tcontDescriptorArray));
#endif

	memset(dsTrtcmTable, 0xff, sizeof(dsTrtcmTable));

#if defined(TCSUPPORT_GPON_DOWNSTREAM_MAPPING)
	//gpon down queue map api
	if (GPONMAP_SUCCESS  == cleanGemDownstreamMappingRule())
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "omciEmptyQueueMappingRule: empty down queue mapping rule\n");		
	}
#endif

#ifdef TCSUPPORT_CDS
	//Init Gem Rate limit
	int chanID=0;
	for(chanID=0;chanID<UP_GEMPORT_TO_METER_NUM;chanID++){
		blapi_traffic_set_pon_ratelimit(GEMPORT_DOWN,chanID, 1024000);
		blapi_traffic_set_pon_ratelimit(GEMPORT_UP,chanID, 1024000);
		omci_tcapi_set(OLT_CTRL_RATE_LIMIT_PATH,OLT_CTRL_RATE_LIMIT,"Yes");
	}

#endif
    omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "[%s][%d]leave\n", __FUNCTION__, __LINE__);
	return 0;
fail:
    omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]leave\n", __FUNCTION__, __LINE__);
	return OMCI_CMD_ERROR;

}

int setGEMBlockLengthValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	omci_ani_g_ptr ani_g_info=NULL;

	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}

	ani_g_info = (omci_ani_g_ptr)(me_info->attributes);
	omci_lib_set_gem_block_length(ani_g_info->gemBlockLength);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s]  gemBlockLength = %d\n",__FUNCTION__,ani_g_info->gemBlockLength);

	return 0;
}

int setSFThresholdValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
#ifdef BSP_BUILD
		/*Reference this function pmmgrSetAlarmConfig() for PM*/
	printf("Part of %s is not implementation in bsp mode!\n", __FUNCTION__);
#else 

	omci_ani_g_ptr ani_g_info=NULL;
	char buffer[25] = {0};

	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}

	ani_g_info = (omci_ani_g_ptr)(me_info->attributes);
	sprintf(buffer, "%d", ani_g_info->sfThreshold);
	omci_adpt_set_commit_attriubte("GPON_ANI", "SFThd", buffer);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s] sfThreshold = %d\n",__FUNCTION__,ani_g_info->sfThreshold);
#endif	
	return 0;
}

int setSDThresholdValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
#ifdef BSP_BUILD
		/*Reference this function pmmgrSetAlarmConfig() for PM*/
	printf("Part of %s is not implementation in bsp mode!\n", __FUNCTION__);
#else

	omci_ani_g_ptr ani_g_info=NULL;
	char buffer[25] = {0};

	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}

	ani_g_info = (omci_ani_g_ptr)(me_info->attributes);
	sprintf(buffer, "%d", ani_g_info->sdThreshold);
	omci_adpt_set_commit_attriubte("GPON_ANI", "SDThd", buffer);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s] sdThreshold = %d\n",__FUNCTION__,ani_g_info->sdThreshold);
#endif	
	return 0;
}


int setANIGARCValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	omci_ani_g_ptr ani_g_info=NULL;
	uint8_t ARCEnable = 0;
	evt_arc_data_t arc_data = {0};

	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}

	ani_g_info = (omci_ani_g_ptr)(me_info->attributes);
	ARCEnable = ani_g_info->arc;
	arc_data.class_id = me_info->class_id;
	arc_data.inst_id = me_info->inst_id;
	arc_data.interval = ani_g_info->arcInterval;
	if (ARCEnable == 0)
	{
		arc_data.arc_en = ARC_DISABLE;
		omci_adpt_report_event(OMCI_EVENT_ARC, &arc_data);
	}
	else if (ARCEnable == 1)
	{	
		omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s]: ARC_Interval = %d\n",__FUNCTION__, arc_data.interval);
		arc_data.arc_en = ARC_DISABLE;
		omci_adpt_report_event(OMCI_EVENT_ARC, &arc_data);
		arc_data.arc_en = ARC_ENABLE;
		omci_adpt_report_event(OMCI_EVENT_ARC, &arc_data);
	}
	else
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "setANIGARCValue: ARCEnable unknown value\n");
		return -1;
	}
	
	return 0;
}

int setANIGARCIntervalValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	omci_ani_g_ptr ani_g_info=NULL;
	uint8_t ARCEnable = 0;
	evt_arc_data_t arc_data = {0};
	
	if(me_info == NULL ||	me_info->attributes==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}

	ani_g_info = (omci_ani_g_ptr)(me_info->attributes);
	ARCEnable = ani_g_info->arc;
	arc_data.class_id = me_info->class_id;
	arc_data.inst_id = me_info->inst_id;
	arc_data.interval = ani_g_info->arcInterval;
	if (ARCEnable == 0)
	{
		arc_data.arc_en = ARC_DISABLE;
		omci_adpt_report_event(OMCI_EVENT_ARC, &arc_data);
	}
	else if (ARCEnable == 1)
	{
		arc_data.arc_en = ARC_DISABLE;
		omci_adpt_report_event(OMCI_EVENT_ARC, &arc_data);
		arc_data.arc_en = ARC_ENABLE;
		omci_adpt_report_event(OMCI_EVENT_ARC, &arc_data);
	}
	else
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "setANIGARCIntervalValue: ARCEnable unknown value\n");
		return -1;
	}

	return 0;
}


float logFunction(float x, int base, int decimalplaces)
{
	int integer = 0;
	float return_value = 0;
	float decimalplaces_count = 0.1;
	if (x <= 0.0)
		return -40; //assume it is x = 1 when x is 0.
	
	while(x < 1)
	{
		integer = integer -1;
		x = x*base;
	}
	while(x >= base)
	{
		integer = integer + 1;
		x = x/base;
	}
	return_value = integer;
	while(decimalplaces > 0)
	{
		x = x*x*x*x*x*x*x*x*x*x;
		int digit = 0;
		while (x >= base)
		{
			digit = digit + 1;
			x = x/base;
		}

		return_value = return_value + (digit * decimalplaces_count);
		decimalplaces = decimalplaces - 1;
		decimalplaces_count = decimalplaces_count * 0.1;
	}

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "log_value : %f\n", return_value);
	return return_value;
}

int getOpticalSignalLevelValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	omci_ani_g_ptr ani_g_info=NULL;
	float power_uw = 0.0;
	short rxPower = 0;
	float log_value = 0.0;

	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}
	ani_g_info = (omci_ani_g_ptr)(me_info->attributes);
	
	PHY_PARAMS_t pPhyTransParams;
	memset(&pPhyTransParams,0,sizeof(PHY_PARAMS_t));
	gponmgr_lib_get_phy_trans_params(&pPhyTransParams);

	power_uw =	pPhyTransParams.rxPower * 0.1;
	log_value = 10*(logFunction(power_uw, 10, 4) - 3);
	rxPower = (short)(log_value * 500);
	ani_g_info->opticalSignalLevel = rxPower;
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s]: opticalSignalLevel = %d\n",__FUNCTION__, ani_g_info->opticalSignalLevel);
	
	return 0;
}

int setLowerOpticalThresholdValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	omci_ani_g_ptr ani_g_info=NULL;

	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}

	ani_g_info = (omci_ani_g_ptr)(me_info->attributes);
	
	omci_lib_set_rxPower_lowerThreshold(ani_g_info->lowerOpticalThreshold);

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s] lowerOpticalThreshold = %d\n",__FUNCTION__,ani_g_info->lowerOpticalThreshold);
	
	return 0;
}

int setUpperOpticalThresholdValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	omci_ani_g_ptr ani_g_info=NULL;

	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}

	ani_g_info = (omci_ani_g_ptr)(me_info->attributes);
	
	omci_lib_set_rxPower_upperThreshold(ani_g_info->upperOpticalThreshold);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s] upperOpticalThreshold = %d\n",__FUNCTION__,ani_g_info->upperOpticalThreshold);

	return 0;
}

int getTransmitOpticalLevelValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	omci_ani_g_ptr ani_g_info=NULL;
	float power_uw = 0.0;
	int16_t txPower = 0;
	float log_value = 0.0;
	PHY_PARAMS_t pPhyTransParams;

	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}
	ani_g_info = (omci_ani_g_ptr)(me_info->attributes);

	memset(&pPhyTransParams,0,sizeof(PHY_PARAMS_t));
	gponmgr_lib_get_phy_trans_params(&pPhyTransParams);

	power_uw = pPhyTransParams.txPower * 0.1;
	log_value = 10*(logFunction(power_uw, 10, 4) - 3);
	txPower = (int16_t)(log_value * 500);
	ani_g_info->transmitOpticalLevel = txPower;
	omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] transmitOpticalLevel = %d\n",__FUNCTION__,ani_g_info->transmitOpticalLevel);

	return 0;
}

int setLowerTransmitOpticalThresholdValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	omci_ani_g_ptr ani_g_info=NULL;

	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}

	ani_g_info = (omci_ani_g_ptr)(me_info->attributes);

	omci_lib_set_txPower_lowerThreshold(ani_g_info->lowerTransmitPowerThreshold);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s] lowerTransmitPowerThreshold = %d\n",__FUNCTION__,ani_g_info->lowerTransmitPowerThreshold);

	return 0;
}

int setUpperTransmitOpticalThresholdValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{

	omci_ani_g_ptr ani_g_info=NULL;

	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}

	ani_g_info = (omci_ani_g_ptr)(me_info->attributes);

	omci_lib_set_txPower_upperThreshold(ani_g_info->upperTransmitPowerThreshold);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s] upperTransmitPowerThreshold = %d\n",__FUNCTION__,ani_g_info->upperTransmitPowerThreshold);

	return 0;
}
static inline int getTrtcChan4Gemport(uint16_t gemPortId, uint16_t direction)
{
    uint8_t channelId = 0;
    uint16_t *trtcmTable = NULL;
    uint16_t tableLen = 0;

    if(direction == UPSTREAM_GEMPORT){
        trtcmTable = trtcmChannel;
        tableLen = TRTCM_CHAN_NUM_FOR_GEMPORT;
    }
    else if(direction == DOWNSTREAM_GEMPORT){
        trtcmTable = dsTrtcmTable;
        tableLen = CONST_DS_TRTCM_NUMBER;
    }
    else
        return -1;

    /* search the id using channel id */
    for (channelId = 0; channelId < tableLen; channelId++)
    {
            if (gemPortId == trtcmTable[channelId])
                    return channelId;
    }
  
    /* if the id is not using channel, then select an avaible channel for Trtcm*/
    for (channelId = 0; channelId < tableLen; channelId++)
    {
            if (INVALID_GEMPORTID == trtcmTable[channelId])
                    break;
    }

    return channelId;

}

int setDsTrtcmRateLimitBySwitch(TrtcmParam trtcm)
{
    mt7530_switch_api_trtcm_t trtcm_switch;
    int ret = 0;

    if ((trtcm.CIR == 0) || (trtcm.CIR > 65535 * 8000))
    {
        trtcm.CIR = 65535 * 8000 ;
    }

    if ((trtcm.PIR == 0) || (trtcm.PIR > 65535 * 8000))
    {
        trtcm.PIR = 65535 * 8000;
    }

    if (trtcm.CIR > trtcm.PIR)
        trtcm.CIR = trtcm.PIR;

/* local setting */
    if ((trtcm.CBS == 0) ||(trtcm.CBS > 0xffff))
    {
        trtcm.CBS = 0xffff;
    }

/* local setting */
    if ((trtcm.PBS == 0) || (trtcm.PBS > 0xffff))
    {
        trtcm.PBS = 0xffff;
    }

    if (trtcm.CBS > trtcm.PBS)
        trtcm.CBS = trtcm.PBS;

    if (dsTrtcmEnableFlag == 0)
	{
		macMT7530SetDsTrtcmEnable(1);
		dsTrtcmEnableFlag = 1;
	}
    
/* 7530 switch api*/	
    memset(&trtcm_switch, 0, sizeof(trtcm_switch));
    trtcm_switch.trtcmId = trtcm.chanID;
    trtcm_switch.CBS = trtcm.CBS;
    trtcm_switch.PBS = trtcm.PBS;
    trtcm_switch.CIR = trtcm.CIR/8000;
    trtcm_switch.PIR = trtcm.PIR/8000;
    ret = macMT7530SetDsTrtcm(&trtcm_switch);

    return ret;

}
static int setTrtcmUsedByGemportMapping(uint16_t gemPortId, uint8_t channel, uint16_t direction)
{

    uint16_t *trtcmTable = NULL;
    uint16_t tableLen = 0;

    if(direction == UPSTREAM_GEMPORT){
        trtcmTable = trtcmChannel;
        tableLen = TRTCM_CHAN_NUM_FOR_GEMPORT;
    }
    else if(direction == DOWNSTREAM_GEMPORT){
        trtcmTable = dsTrtcmTable;
        tableLen = CONST_DS_TRTCM_NUMBER;
    }
    else
        return -1;

    if ((channel >= tableLen) || \
        (INVALID_GEMPORTID == gemPortId)){
            return -1;
    }
    
    trtcmTable[channel] = gemPortId;
    return 0;
}

int setQueueMappingTrtcmPara(uint16_t gemPortId, uint16_t tdPointerInstanceId , uint16_t direction)
{
    int ret = 0;
    int trtcmTableLen = 0;
    int chanID = 0;
    uint64_t pir_bps = 0;   
    uint32_t pir_kbps = 0;
	
	omci_me_info_t me_info={0};
	omci_traffic_descriptor_ptr traffic_desc_ptr=NULL;
	
	me_info.class_id = OMCI_CLASS_ID_TRAFFIC_DESCRIPTOR;
	me_info.inst_id = tdPointerInstanceId;
	if(omci_attr_get_all_data_except_table_attr(&me_info) != 0){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] [%d]:, goto fail!\n",__FILE__, __LINE__);
		return INVALID_TRTCM_CHAN;
	}

	traffic_desc_ptr = (omci_traffic_descriptor_ptr)(me_info.attributes);
	
	if (0 == traffic_desc_ptr->pir)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "[%s][%d] traffic descriptor PIR = 0, use factory PIR config(not speed limit)\n",__FUNCTION__, __LINE__);
        return INVALID_TRTCM_CHAN;
	}
    pir_bps = traffic_desc_ptr->pir; //bytes unit   
    pir_bps = pir_bps*8;             // bytes to bits

    if(direction == UPSTREAM_GEMPORT){
        trtcmTableLen = TRTCM_CHAN_NUM_FOR_GEMPORT;
    }else if(direction == DOWNSTREAM_GEMPORT){
        trtcmTableLen = CONST_DS_TRTCM_NUMBER;
    }
    else
        return -1;
   
	
/*avaliable trtcm channel*/
    chanID= getTrtcChan4Gemport(gemPortId,direction);
    if ( (chanID == trtcmTableLen) || (chanID == -1) )
    {
            omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"no avaible channel for trtcm, chanID(%d) trtcmTableLen(%d) gemPortId(%d)  direction(%d)\n",chanID,trtcmTableLen,gemPortId,direction);   
            return -1;
    }

    pir_kbps = pir_bps/1000;  //bits to kb
    if(direction == UPSTREAM_GEMPORT){
        blapi_traffic_set_pon_ratelimit(GEMPORT_UP,chanID,pir_kbps);
        omcidbgPrintf(OMCI_DEBUG_LEVEL_NO_MSG, "[%s] [%d]: === gemPortId=%d,chanID=%d pir=%d ====== \n",
            __FUNCTION__, __LINE__,gemPortId,chanID,pir_kbps);

    }
    else if(direction == DOWNSTREAM_GEMPORT){
        blapi_traffic_set_pon_ratelimit(GEMPORT_DOWN,chanID,pir_kbps);
    }

	omci_tcapi_set(OLT_CTRL_RATE_LIMIT_PATH,OLT_CTRL_RATE_LIMIT,"Yes");

    ret = setTrtcmUsedByGemportMapping(gemPortId, chanID, direction);
    if (ret != 0)
          return -1;

    return chanID;
}

#if/*TCSUPPORT_COMPILE*/ defined(TCSUPPORT_ALPHION_PON)
int setChannelTxRateLimit(uint16_t InstanceId , uint8_t tcontIdx)
{
	uint16_t tmpUpInstanceId = 0;
    uint32_t pir = 0;
	uint32_t totalLimitValue = 0;
  	int ret = 0;
	int j = 0;
	struct XMCS_GponTxRateLimit_S txRateLimitdata = {0};
	omci_me_info_t me_info={0};
	omci_traffic_descriptor_ptr traffic_desc_ptr=NULL;

	omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] InstanceId=%d tsChannelId = %d\n", __func__,__LINE__,InstanceId,tcontIdx);
	
	me_info.class_id = OMCI_CLASS_ID_TRAFFIC_DESCRIPTOR;
	me_info.inst_id = InstanceId;
	if(omci_attr_get_all_data_except_table_attr(&me_info) != 0){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] [%d]: get data fail!\n",__FILE__, __LINE__);
		return -1;
	}

	traffic_desc_ptr = (omci_traffic_descriptor_ptr)(me_info.attributes);
    pir = traffic_desc_ptr->pir;
	if(pir == 0)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] [%d]: tdPointerUpInstanceId is %d pir is %d\n",__FILE__, __LINE__,InstanceId,pir);
		return 0;
	}

	totalLimitValue += pir;
	for(j=0;j<8;j++)
	{
		if(tcontDescriptorArray[tcontIdx][j] == 0)
		{	
			continue;
		}
		else
		{
			tmpUpInstanceId = tcontDescriptorArray[tcontIdx][j];
			me_info.class_id = OMCI_CLASS_ID_TRAFFIC_DESCRIPTOR;
			me_info.inst_id = tmpUpInstanceId;
			if(omci_attr_get_all_data_except_table_attr(&me_info) != 0){
				omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] [%d]: get data fail!\n",__FILE__, __LINE__);
				return -1;
			}
			traffic_desc_ptr = (omci_traffic_descriptor_ptr)(me_info.attributes);
			pir = traffic_desc_ptr->pir;
			totalLimitValue += pir;
		}
	}
	
	txRateLimitdata.chnlIdx = tcontIdx;
	txRateLimitdata.chnlRateLimitEn = 1;
	txRateLimitdata.rateLimitValue = totalLimitValue;
	omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] setChannelTxRateLimit,tsChannelId is %d chnlRateLimitEn is %d rateLimitValue is %d byte per second \n", 
	                            __func__,__LINE__,tcontIdx,txRateLimitdata.chnlRateLimitEn,txRateLimitdata.rateLimitValue);
	ret = gponmgr_lib_set_tx_rate_limit(&txRateLimitdata);
	if(ret != 0)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] [%d]: ioctl tx rate limit fail,ret is  %d\n",__FILE__, __LINE__,ret);
		return -1;
	}
	return 0;	
}
#endif/*TCSUPPORT_COMPILE*/

// 9.2.2 T-CONT
int omciAddQueueMappingRule(omci_gem_port_ctp_ptr gem_ctp_ptr)
{
#ifndef TCSUPPORT_GPON_MAPPING
	printf("Part of %s is not implement, not support GPON_MAPPING!\n", __FUNCTION__);
	return 0;
#endif

	int ret = 0;
	uint16_t gemPortId = 0;
	uint16_t tcontInstanceId = 0;
	uint8_t direction = 0;
	uint8_t gemPortType = 0;
	uint16_t tcontAllocId = 0;
	uint8_t TMOption = 0;
	uint16_t TMPointerUpInstanceId = 0;
	uint16_t tdPointerUpInstanceId = 0;
	uint16_t tdPointerDownInstanceId = 0;
	uint16_t PQPointerDownInstanceId = 0;
	int tsChannelId = 0;
	int tsDsTrtcmId = 0;
	uint8_t queueId  = 0;
	uint16_t queuePriority = 0;
	uint8_t lanPortId = 0;
	uint8_t downQueueId = 0;
	uint8_t queueFlag = 0; /* multi queue, or specfic queue*/
	uint8_t descriptorFlag = 0;  			/*traffic shaping enable/disable*/
	uint8_t downDescriptorFlag = 0;
	gponQueueMappingIoctl_t data;
	int isDsTrtcmSupport = 1;
#if defined(TCSUPPORT_ALPHION_PON)
	uint tmpRepeatFlag = 0;
	int j = 0;
#endif
#if defined(TCSUPPORT_GPON_DOWNSTREAM_MAPPING)
	/*gpon down queue map api*/
	uint8_t if_mask = 0;
#endif
	struct XMCS_GponTcontInfo_S  tcontInfo = {0};
    tcontidx = 0;

	omci_me_info_t me_info={0};
	omci_onu_g_ptr onu_g_ptr=NULL;
	omci_priority_queue_ptr pq_ptr=NULL;
	omci_t_cont_ptr tont_ptr=NULL;

	if (gem_ctp_ptr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] [%d]: goto fail!\n",__FILE__, __LINE__);
		goto fail;
	}
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s] [%d]:\n",__FILE__, __LINE__);

/*3------Direction*/
	direction = gem_ctp_ptr->direction;
	if (direction == DIRECTION_ANI_TO_UNI)
	{
		gemPortType = GEM_TYPE_MULTICAST;
	}
	else if (direction == DIRECTION_BIDIRECTIONAL)
	{
		gemPortType = GEM_TYPE_UNICAST;
	}
	
/*1------Gem port Id*/
	gemPortId = gem_ctp_ptr->portId;

/*2------T-CONT pointer*/
	tcontInstanceId = gem_ctp_ptr->tcontPointer;

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s] [%d]: gemPortId=%d,gemPortType=%d,direction=%d,tcontInstId=%d\n",
		__FILE__, __LINE__,gemPortId,gemPortType,direction,tcontInstanceId);

	/*Alloc-Id*/
	if ((direction != DIRECTION_ANI_TO_UNI) && 
		((tcontInstanceId >= T_CONT_INST_START_ID) && 
		(tcontInstanceId <= (T_CONT_INST_START_ID + T_CONT_TOTAL_NUM - 1))))
	{
		me_info.class_id = OMCI_CLASS_ID_T_CONT;
		me_info.inst_id= tcontInstanceId;

		if(omci_attr_get_all_data_except_table_attr(&me_info) != 0){
			omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s] get attribute data fail\n",__FUNCTION__);
			goto fail;
		}
		
		tont_ptr = (omci_t_cont_ptr)(me_info.attributes);
		if(tont_ptr == NULL){
			omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s] gem_port_ctp_info==NULL\n",__FUNCTION__);
			goto fail;
		}

		tcontAllocId = tont_ptr->allocId;
	}
	else
	{
		tcontAllocId = 0xFFFF;
	}

/*4-------TMPointerUp*/
	me_info.class_id = OMCI_CLASS_ID_ONU_G;
	me_info.inst_id = 0;
	if(omci_attr_get_all_data_except_table_attr(&me_info) != 0){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] [%d]:, goto fail!\n",__FILE__, __LINE__);
		goto fail;
	}
	onu_g_ptr =(omci_onu_g_ptr)(me_info.attributes);
	TMOption = onu_g_ptr->trafficMgrOp;

	if (TMOption == 1)
	{
		/*point to T-CONT, no need to handle*/
	}
	else if(TMOption == 0 || TMOption == 2)
	{
		TMPointerUpInstanceId = gem_ctp_ptr->TrafficManagePointerUp;
		if ((direction != DIRECTION_ANI_TO_UNI) && (TMPointerUpInstanceId != 0) && (TMPointerUpInstanceId != 0xFFFF))
		{/*upstream priority queue is setted by OLT.*/
			/*priority queue id*/
			me_info.class_id = OMCI_CLASS_ID_PRIORITY_QUEUE;
			me_info.inst_id = TMPointerUpInstanceId;
			if(omci_attr_get_all_data_except_table_attr(&me_info) == -1)
			{
				if(TMOption == 2)
				{
				    me_info.class_id = OMCI_CLASS_ID_TRAFFIC_SCHEDULER;
        			me_info.inst_id = TMPointerUpInstanceId;
        			if(omci_attr_get_all_data_except_table_attr(&me_info) == -1){
        			    omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] [%d]: get data fail, classId=%d, inst_id=%x\n",__FILE__, __LINE__,me_info.class_id , me_info.inst_id);
        			    goto fail;
        			}
				}
				else
				{
				    omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] [%d]: get data fail, classId=%d, inst_id=%x\n",__FILE__, __LINE__,me_info.class_id , me_info.inst_id);
				    goto fail;
				}
			}
			if(me_info.class_id == OMCI_CLASS_ID_PRIORITY_QUEUE)
			{
    			pq_ptr =(omci_priority_queue_ptr)(me_info.attributes);
    			omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s] [%d]:relatedPort=0x%x,queuePriority=0x%x\n",__FILE__, __LINE__,pq_ptr->relatedPort,queuePriority);
    			queuePriority = (uint16_t)(pq_ptr->relatedPort & 0x0000ffff);
    			queueId = (7 -((uint8_t)queuePriority & 0x07));
    			omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s] [%d]:queuePriority=%d,queueId=%d\n",__FILE__, __LINE__,queuePriority,queueId);
    			queueFlag = TRAFFIC_SCHEDULER_SPECIFIC_QUEUE_MODE;
			}
			else
			{
			    //traffic scheduler do nothing
			    queueFlag = TRAFFIC_SCHEDULER_SPECIFIC_QUEUE_MODE;
			}
		}
		else
		{/*upstream priority queue is not setted by OLT.*/
			queueFlag = TRAFFIC_SCHEDULER_MULTI_QUEUE_MODE; 
		}
	}
	else
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "the Traffic management Option is wrong\n");
		goto fail;
	}
	
/*5------TDPointerUp	*/
	if (TMOption == 0)
	{
		/*TDPointerUp is not used, no need to handle*/
	}
	else /*if(TMOption == 1 || TMOption == 2)*/
	{
		tdPointerUpInstanceId = gem_ctp_ptr->TrafficDescriptorPointerUp;
		if ((direction != DIRECTION_ANI_TO_UNI)
            && (tdPointerUpInstanceId != 0) && (tdPointerUpInstanceId != 0xFFFF) )
		{/*upstream traffic descriptor is setted by OLT.*/
			descriptorFlag = TRAFFIC_SHAPING_ENABLE;
			if (0xFFFF != tcontAllocId)
			{
				tcontInfo.allocId = tcontAllocId;
				//omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%5d][%s] tcontInfo.allocId is %d\n",__LINE__, __func__,tcontInfo.allocId);
				ret = gponmgr_lib_get_tcont_index(&tcontInfo);
				if(ret)
				{
					omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%5d][%s] get tcont idx fail,tcontAllocId is %d tcontIdx is %d ret %d\n",__LINE__, __func__,tcontInfo.allocId,tcontInfo.tcontIdx,ret);
				}
				tcontidx = tcontInfo.tcontIdx;
				omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%5d][%s] tcontInfo.allocId is %d and tcont.tcontIdx is %d\n",__LINE__, __func__,tcontInfo.allocId,tcontInfo.tcontIdx);
    			/*set trtcm parameter: channel, cir, pir, cbs, pbs*/
    			ret = setQueueMappingTrtcmPara(gemPortId, tdPointerUpInstanceId, UPSTREAM_GEMPORT);
    			if (ret == -1){
    				omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] [%d]:, goto fail!\n",__FILE__, __LINE__);
    				goto fail;
    			}else{
					tsChannelId = ret;
				}

				if (INVALID_TRTCM_CHAN == tsChannelId)
				{
					descriptorFlag = TRAFFIC_SHAPING_DISABLE;
				}

#if/*TCSUPPORT_COMPILE*/ defined(TCSUPPORT_ALPHION_PON)
				for(j=0;j<8;j++)
				{
					if(tcontDescriptorArray[tcontInfo.tcontIdx][j] == 0)
					{
						tcontDescriptorArray[tcontInfo.tcontIdx][j] = tdPointerUpInstanceId;
						break;
					}
					if(tcontDescriptorArray[tcontInfo.tcontIdx][j] == tdPointerUpInstanceId)
					{
						tmpRepeatFlag = 1;
						break;
					}
				}
				if(j == 8)
				{
					omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%5d][%s] tcontInfo.tcontIdx is %d tdPointerUpInstanceId is %d,descriptor num is out of 8\n",__LINE__, __func__,tcontInfo.tcontIdx,tdPointerUpInstanceId);
				}
				else
				{
					if(!tmpRepeatFlag)
					{
						//omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%5d][%s] before setChannelTxRateLimit tcontIdx is %d tdPointerUpInstanceId is %d\n",__LINE__, __func__,tcontInfo.tcontIdx,tdPointerUpInstanceId);
						ret = setChannelTxRateLimit(tdPointerUpInstanceId, tcontInfo.tcontIdx);
						if (ret != 0){							
							goto fail;
						}
					}
				}
#endif/*TCSUPPORT_COMPILE*/
			}
			omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%5d][%s]\n",__LINE__, __func__);
		}
		else
		{/*upstream traffic descriptor is not setted by OLT.*/
			descriptorFlag = TRAFFIC_SHAPING_DISABLE;
		}
	}
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s] [%d]:\n",__FILE__, __LINE__);

/*7------PQPointerDown	*/
	PQPointerDownInstanceId = gem_ctp_ptr->PriorityQueuePointerDown;
		
	/*priority queue id*/
	if (PQPointerDownInstanceId != 0xFFFF &&  ((PQPointerDownInstanceId != 0x0) || bbf247_enable))
	{
		me_info.class_id = OMCI_CLASS_ID_PRIORITY_QUEUE;
		me_info.inst_id = PQPointerDownInstanceId;
		if(omci_attr_get_all_data_except_table_attr(&me_info) == -1){
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: goto data fail! inst_id=%d\n",__FILE__, __LINE__,me_info.inst_id);
            goto fail;
		}
		pq_ptr =(omci_priority_queue_ptr)(me_info.attributes);
		lanPortId = (uint8_t) (pq_ptr->relatedPort >> 16 & 0x00ff);
		queuePriority = (uint16_t)(pq_ptr->relatedPort & 0x0000ffff); 
		downQueueId = 7 - (uint8_t) queuePriority;
		
	}
#ifdef TCSUPPORT_CDS
        // downstream gemport mapping to queue by priority queue
        if(downQueueId <8 )
            downQueueId = 7 - downQueueId;
        // downstream boardcast gemport mapping to queue0
        if(gemPortId == 4095 )
            tsChannelId = 0;
        // downstream multicast gemport mapping to queue7
        if(gemPortId == 4094 )
            tsChannelId = 7;
        //  more than 8 gemport, other gemport is mapping to Queue 0
        if(tsChannelId >= 8)
            tsChannelId = 0;
#endif

/*9------TDPointerDown	*/
	if (TMOption == 0)
	{
		/*TDPointerDown is not used, no need to handle*/
	}
	else /*if(TMOption == 1 || TMOption == 2)*/
	{
		tdPointerDownInstanceId = gem_ctp_ptr->TrafficDescriptorPointerDown;

		if(TCSUPPORT_CUC_VAL)
			isDsTrtcmSupport = 0;
		
		if (isDsTrtcmSupport && ((tdPointerDownInstanceId != 0) && (tdPointerDownInstanceId != 0xFFFF)))
		{/*downstream traffic descriptor is setted by OLT.*/
			downDescriptorFlag = TRAFFIC_SHAPING_ENABLE;
			
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%5d][%s]\n",__LINE__, __func__);
			/*set trtcm parameter: channel, cir, pir, cbs, pbs*/
			tsDsTrtcmId = setQueueMappingTrtcmPara(gemPortId, tdPointerDownInstanceId, DOWNSTREAM_GEMPORT);
			if (tsDsTrtcmId == -1)
#ifdef TCSUPPORT_CHS
				tsDsTrtcmId = setQueueMappingTrtcmPara(gemPortId, 0xFFFF, DOWNSTREAM_GEMPORT);
				if (tsDsTrtcmId == -1)
#endif
				goto fail;

			if (INVALID_TRTCM_CHAN == tsDsTrtcmId)
			{
				downDescriptorFlag = TRAFFIC_SHAPING_DISABLE;
			}
		}
		else
		{/*downstream traffic descriptor is not setted by OLT.*/
#ifdef TCSUPPORT_CDS
		    tsDsTrtcmId = setQueueMappingTrtcmPara(gemPortId, tdPointerDownInstanceId, DOWNSTREAM_GEMPORT);
		    if (tsDsTrtcmId == -1)
		        goto fail;
#endif
			downDescriptorFlag = TRAFFIC_SHAPING_DISABLE;
		}
		
	}

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "omciQueueMapping:gemPort = %x, gemPortType = %x, pqMode = %x, queue = %x, tcontAllocId = %x, tsEnable = %x, tsChannelId = %x\n", 
											gemPortId, gemPortType, queueFlag, queueId, tcontAllocId, descriptorFlag, tsChannelId);
/*gpon up queue map api*/
	memset(&data, 0, sizeof(gponQueueMappingIoctl_t));
	data.gemPort = gemPortId;
	data.gemType = gemPortType;
	data.pqMode = queueFlag;
	data.queue = queueId;
	data.allocId = tcontAllocId;
	data.tsEnable = descriptorFlag;
	data.tsChannelId = tsChannelId;
	
	ret = addQueueMappingRule(&data);
	if (ret == GPONMAP_SUCCESS)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "omciQueueMapping: add the rule success\n");
	}
	else
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "omciQueueMapping: add the rule fail\n");	
		goto fail;
	}	
	recordQueueMapInfo(GEM_PQ_MAP_ACTION_ADD,gemPortId,queueId,TMPointerUpInstanceId,tcontAllocId,gem_ctp_ptr->tcontPointer);

#if defined(TCSUPPORT_GPON_DOWNSTREAM_MAPPING)
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "omciQueueMapping:gemPort = %x, lanPortId = eth0.%d, downQueueId = %x, downTrtcmId = %x\n", gemPortId, lanPortId, downQueueId, tsDsTrtcmId);
	if (lanPortId == 0)
		lanPortId = 1;
    
    /* gpon down queue map api. fix the wifi packets dropped in ds mapping. */
    if_mask = 0xFF;



	gpon_downstream_mapping_ioctl ds_rule;
	memset(&ds_rule, 0, sizeof(ds_rule));
	ds_rule.gem_port_num = gemPortId;
	ds_rule.if_mask = if_mask;
	ds_rule.queue = downQueueId;
	ds_rule.trtcmId = INVALID_TRTCM_CHAN ? 0 : tsDsTrtcmId;
    ds_rule.ds_pq_enable = (((PQPointerDownInstanceId != 0) || bbf247_enable) && (PQPointerDownInstanceId != 0xffff)) ? ENABLE : DISABLE;
    ds_rule.ds_trtcm_enable = downDescriptorFlag;
	ds_rule.option_flag = OPT_SET;

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%d][%s] linkMode=%d\n",__LINE__, __func__,omci_onu_cap_g.linkMode);
	if((omci_onu_cap_g.linkMode == OMCI_MODE_XGPON)||(omci_onu_cap_g.linkMode == OMCI_MODE_XGSPON)
		|| (omci_onu_cap_g.linkMode == OMCI_MODE_NG2_10G_10G))	
	{
		if(ds_rule.gem_port_num > MAX_GEMPORT_ID_NUM_10G)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "downstream gemport id number is more than 10G maximum fail!\n");
			goto fail;
		}
	}
	else 
	{
		if(ds_rule.gem_port_num > MAX_GEMPORT_ID_NUM_1G)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "downstream gemport id number is more than 1G maximum fail!\n");
			goto fail;
		}
	}
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%5d][%s]  call addGemDownstreamMappingRule! ds_rule.queue=%d\n",
		__LINE__, __func__,ds_rule.queue);
	ret = addGemDownstreamMappingRule(ds_rule);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%5d][%s] addGemDownstreamMappingRule done\n", __LINE__, __func__);

	if (ret == GPONMAP_SUCCESS)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%5d][%s] success!\n", __LINE__, __func__);
	}
	else
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%5d][%s] fail!\n", __LINE__, __func__);
		goto fail;
	}	
#endif
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%5d][%s] return success!\n", __LINE__, __func__);
	return 0;
fail:
	omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%5d][%s] return fail!!\n", __LINE__, __func__);
	return OMCI_CMD_ERROR;
}

int omciDelQueueMappingRule(omci_gem_port_ctp_ptr gem_ctp_ptr)
{
	int ret = 0;
	uint16_t gemPortId = 0;
	gponQueueMappingIoctl_t data;

	if (gem_ctp_ptr == NULL ){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] [%d]: goto fail!\n",__FILE__, __LINE__);
		goto fail;
	}
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s] [%d]:\n",__FILE__, __LINE__);
	
/*Gem port Id*/
	gemPortId = gem_ctp_ptr->portId;

/*gpon queue map api*/
	memset(&data, 0, sizeof(gponQueueMappingIoctl_t));
	data.gemPort = gemPortId;

	recordQueueMapInfo(GEM_PQ_MAP_ACTION_DEL,data.gemPort,0,0,0,0); //only need gemPort while delete
	ret = delQueueMappingRule(&data);
	if (ret == GPONMAP_ENTRY_NOT_FOUND)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "omciDelQueueMappingRule:GPONMAP_ENTRY_NOT_FOUND\n");
	}
	else if (ret == GPONMAP_SUCCESS)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "omciDelQueueMappingRule: delete old queue mapping rule\n");		
	}
	else if (ret == GPONMAP_FAIL)
	{	
		omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "omciDelQueueMappingRule: delete queue mapping rule fail\n");		
		goto fail;
	}
	
#if defined(TCSUPPORT_GPON_DOWNSTREAM_MAPPING)
	/*gpon down queue map api*/
	if (GPONMAP_SUCCESS == delGemDownstreamMappingRule(gemPortId))
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "omciDelQueueMappingRule: delete old down queue mapping rule\n");		
	}
#endif

	return 0;
fail:
	return OMCI_CMD_ERROR;
}

int omciReconfigQueueMappingRule(void)
{
	int ret = 0;

	gponQueueMappingIoctl_t data;

/*gpon queue map api*/
	memset(&data, 0, sizeof(gponQueueMappingIoctl_t));
	data.gemPort = RECONFIG_GPONMAP_RULE;
	
	ret = addQueueMappingRule(&data);

 	if (ret == GPONMAP_SUCCESS)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "omciReconfigQueueMappingRule: add queue mapping rule\n");		
	}
	else 
	{	
		omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "omciReconfigQueueMappingRule: add queue mapping rule fail\n");		
		goto fail;
	}
	
	return 0;
fail:
	return OMCI_CMD_ERROR;
}

int omci_me_ani_g_test_op(management_entry_ptr me_entry, omci_me_info_ptr me_info)
{
    int ret = 0;
	int phyPara[5] = {0};
	PHY_PARAMS_t pPhyTransParams;
	uint8_t *tmp = NULL;
	uint16_t return_value = 0;
	float log_value = 0.0;
	float power_uw = 0.0;
	evt_test_result_data_t eventTestData;

    omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "Enter [%s][%d].\n",__FUNCTION__,__LINE__);
	if((NULL == me_entry)||(NULL == me_info) ||(NULL == me_info->attributes)){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]Parameter is Null.\n",__FUNCTION__,__LINE__);
		ret = -1;
		goto end;
	}
	
	memset(&pPhyTransParams,0,sizeof(PHY_PARAMS_t));
	gponmgr_lib_get_phy_trans_params(&pPhyTransParams);
	phyPara[0] = pPhyTransParams.temperature;
	phyPara[1] = pPhyTransParams.voltage;
	phyPara[2] = pPhyTransParams.txCurrent;
	phyPara[3] = pPhyTransParams.txPower;
	phyPara[4] = pPhyTransParams.rxPower;

	/*send test result packets*/
	/*ANI test type 1 cmd--Voltage*/
	tmp = (uint8_t *)(me_info->attributes);
	*tmp = 1;
	put16(tmp+1, ((uint16_t)phyPara[1]/200));
    
	/*ANI test type 2 cmd--RxPower*/
	tmp = tmp + 3;
	*tmp = 3;
	power_uw = phyPara[4] * 0.1;
	log_value = 10*logFunction(power_uw, 10, 4);
	return_value = (short)(log_value * 500);
	put16(tmp+1, return_value);
    
	/*ANI test type 3 cmd--TxPower*/
	tmp = tmp + 3;
	*tmp = 5;
	power_uw = phyPara[3] * 0.1;
	log_value = 10*logFunction(power_uw, 10, 4);
	return_value = (short)(log_value * 500);
	put16(tmp+1, return_value);
    
	/*ANI test type 4 cmd--TxCurrent*/
	tmp = tmp + 3;
	*tmp = 9;
	put16(tmp+1, (uint16_t)phyPara[2]);
    
	/*ANI test type 5 cmd--Temperature*/
	tmp = tmp + 3;
	*tmp = 12;
	put16(tmp+1, (uint16_t)phyPara[0]);
	ret = 0;

	if(me_info->dev_id == OMCI_EXTENED_MSG){
		me_info->attr_len = 15; //5 * 3 bytes
	}	

	eventTestData.trans_rel_id = me_info->trans_rel_id;
	eventTestData.dev_id = me_info->dev_id;
	eventTestData.class_id = me_info->class_id;
	eventTestData.inst_id = me_info->inst_id;
	memcpy(eventTestData.test_rest,me_info->attributes,sizeof(eventTestData.test_rest));
	eventTestData.length = me_info->attr_len;
	omci_adpt_report_event(OMCI_EVENT_TEST_RESULT,&eventTestData);
end:
    return ret;
}

int ani_g_test_support(omci_me_info_ptr me_info)
{
    int ret = OMCI_CMD_SUCCESS;

	if(me_info == NULL)
		return OMCI_CMD_ERROR;
	
    if(me_info->attributes[0] <= 0x6){
        ret = OMCI_CMD_NOT_SUPPORT;
    }

    return ret;
}

int setTCONTAllocIdValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	omci_t_cont_ptr tont_ptr=NULL;
	omci_me_info_t me_info_buf={0};
	omci_gem_port_ctp_ptr gem_port_ctp_ptr=NULL;
	int inst_count=0;
	int i=0;
	uint16_t inst_list[MAX_INST_COUNT]={0};
	int result = 0;
	
	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}
	tont_ptr = (omci_t_cont_ptr)(me_info->attributes);

	if(omci_lib_get_inst_count_by_classid(OMCI_CLASS_ID_GEM_PORT_CTP,&inst_count) == -1)
	{
	    omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: omci_lib_get_inst_count_by_classid fail!\n",__FUNCTION__,__LINE__);
		return -1;
	}
	if (omci_lib_get_inst_list_by_classid(OMCI_CLASS_ID_GEM_PORT_CTP,inst_list,MAX_INST_COUNT) == -1){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: omci_lib_get_inst_list_by_classid fail!\n",__FUNCTION__,__LINE__);
		return -1;
	}
	if((tont_ptr->allocId == 0xFF) || (tont_ptr->allocId == 0xFFFF) ){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "[%s] [%d]: alloc id = 0xff/0xffff,do nothing\n",__FUNCTION__,__LINE__);
		return 0;
	}
	for(i=0; i< inst_count; i++)
	{
		if(inst_list[i] != 0){
			me_info_buf.class_id = OMCI_CLASS_ID_GEM_PORT_CTP;
			me_info_buf.inst_id= inst_list[i];
		}
		else 
			break;
		
		if(omci_attr_get_all_data_except_table_attr(&me_info_buf) != 0){
			omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s] get attribute data fail\n",__FUNCTION__);
			break;
		}
		
		gem_port_ctp_ptr = (omci_gem_port_ctp_ptr)(me_info_buf.attributes);
		if(gem_port_ctp_ptr == NULL){
			omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s] gem_port_ctp_info==NULL\n",__FUNCTION__);
			goto fail;
		}
		
		if(gem_port_ctp_ptr->tcontPointer == tont_ptr->meId){
			omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d] gemPort->tcontPointer=%d, tont->instId=%d\n",
				__FUNCTION__,__LINE__,gem_port_ctp_ptr->tcontPointer,tont_ptr->meId);			
			result = omciAddQueueMappingRule(gem_port_ctp_ptr);
			if(result != 0)
				goto fail;
		}

			
	}

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s] return success! allocId=%d\n",__FUNCTION__, tont_ptr->allocId);
	return 0;
	
fail:
	
	omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] return fail! allocId=%d\n",__FUNCTION__, tont_ptr->allocId);
	return -1;
}

int getPonMacQOSParam(uint16_t allocId, uint8_t *qosChannel, uint8_t *qosType ,uint8_t *ponWeight)
{
	int i = 0;
	struct XMCS_ChannelQoS_S wanChannelQos;
	struct XMCS_GponTcontInfo_S tcontInfo = {0};
	uint8_t channel = 0;

	if((0xFFFF == allocId) || (0xFF == allocId)){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]-----allocId=%x-----  \n",__FUNCTION__, __LINE__,allocId );
		return -1;
	}	
	tcontInfo.allocId = allocId;
	gponmgr_lib_get_tcont_index(&tcontInfo);

	channel = tcontInfo.tcontIdx;

	gponmgr_lib_get_qos_scheduler(channel,&wanChannelQos);

	*qosChannel = wanChannelQos.channel;
	*qosType = wanChannelQos.qosType;
	for(i=0; i<8; i++)
	{
	    omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d] get tcont(%d), qosChannel(%d), priority(%d), weight(%d)\n",__FUNCTION__, __LINE__, channel, wanChannelQos.channel, i, wanChannelQos.queue[i].weight);
		ponWeight[i] = wanChannelQos.queue[i].weight;
	}

	if(*qosChannel == 0){
		//channel 0 is for OMCC can't be modify by OMCI, qosChannle will equal to 0 if allocId is default value 0xffff
		omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN, "[%s][%d] allocId=%d get fail!\n",__FUNCTION__, __LINE__,allocId);
		return -1;
	}

	return 0;

}


int setPonMacQOSParam(uint8_t qosChannel, uint8_t qosType, uint8_t *ponWeight)
{
	struct XMCS_ChannelQoS_S wanChannelQos;
	int i;

	if(olt_ctrl_qos_flag == 0  &&  HGU == omci_info_g.onuType){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN,"setPonMacQOSParam: qos controlled by web GUI\n");
		return 0;
	}
	
	wanChannelQos.channel = qosChannel;
	wanChannelQos.qosType = qosType;
	for (i = 0; i < 8; i++){
		wanChannelQos.queue[i].weight = ponWeight[i];
		omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d] set qosChannel(%d), qosType(%d), priority(%d), weight(%d)\n",__FUNCTION__, __LINE__, wanChannelQos.channel, qosType, i, wanChannelQos.queue[i].weight);
	}
	omci_tcapi_set(OLT_CTRL_QOS_PATH,OLT_CTRL_QOS,"Yes");

	return (gponmgr_lib_set_qos_scheduler(&wanChannelQos));
}

int setQOSPolicy(uint16_t allocId, uint8_t qosType)
{
	uint8_t Type = 0;
	uint8_t ponWeight[MAX_NUM_OF_QUEUE_PER_TCONT] = {0};
    uint8_t qosChannel=0;
	int ret=0;
	int i = 0;
	int allWeight = 0;

    ret = getPonMacQOSParam(allocId, &qosChannel, &Type, ponWeight);
    if(ret != 0)
    {       
        omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN,"setWeightValue: getPonMacQOSParam fail!\n");
        return 0;
    }

     switch(qosType) {
        case TCONT_POLICY_WRR:
            Type = 0;//ENUM_QOS_TYPE_WRR;
#if/*TCSUPPORT_COMPILE*/ defined(TCSUPPORT_ALPHION_PON)
			omci_tcapi_set("Qos_Common","Discipline","WRR");
#endif/*TCSUPPORT_COMPILE*/
            break;
        case TCONT_POLICY_SP:
        default:
#if/*TCSUPPORT_COMPILE*/ defined(TCSUPPORT_ALPHION_PON)
			omci_tcapi_set("Qos_Common","Discipline","PQ");
			memset(ponWeight,0,sizeof(ponWeight));
#endif/*TCSUPPORT_COMPILE*/
            Type = 1;//ENUM_QOS_TYPE_SP;
            break;    
    }
    if (Type == 0)
    {
        for(i = 0; i < sizeof(ponWeight); i++)
            allWeight += ponWeight[i];
        if ( allWeight <= 0)
        {
            omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] allocId(%d), qosChannel(%d), qosType(WRR), all weight(%d)\n",__FUNCTION__, __LINE__, allocId, qosChannel, allWeight);
            return 0;
        }
    }
    ret = setPonMacQOSParam(qosChannel, Type, ponWeight);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN,"setQOSPolicy==qosChannel=%d,qosType=%d, ponWeight=%d %d %d %d %d %d %d %d; ret=%d\n",
		qosChannel,qosType,ponWeight[7],ponWeight[6],ponWeight[5],ponWeight[4],ponWeight[3],ponWeight[2],ponWeight[1],ponWeight[0],ret);
    if(ret != 0)
    {       
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setWeightValue: setPonMacQOSParam fail!\n");
        return -1;
    }
    return 0;
}

int setTCONTPolicyValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	uint16_t QosConfFlex = 0;
	int ret=0;
	omci_me_info_t me_info_buf={0};
	omci_onu2_g_ptr onu2_g_ptr=NULL;
	omci_t_cont_ptr tont_ptr=NULL;

	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}
	tont_ptr = (omci_t_cont_ptr)(me_info->attributes);

	me_info_buf.class_id = OMCI_CLASS_ID_ONU2_G;
	me_info_buf.inst_id = 0;
	if(omci_attr_get_all_data_except_table_attr(&me_info_buf) != 0){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s] get attribute data fail\n",__FUNCTION__);
		return -1;
	}

	onu2_g_ptr = (omci_onu2_g_ptr)(me_info_buf.attributes);
	QosConfFlex = onu2_g_ptr->qosCfgFlexibility;

	 /*get ONU2-G QoS configuration flexibility*/
	if(QosConfFlex & 0x0010) /*t-cont me: policy attribute is read-write*/
	{
#ifndef BSP_BUILD
		char tempBuffer[MAX_BUFFER_SIZE] = {0};
		sprintf(tempBuffer, "%x", tont_ptr->meId);
		omci_tcapi_set("GPON_TCONT", "Number", tempBuffer);
		memset(tempBuffer, 0, sizeof(tempBuffer));
		sprintf(tempBuffer, "%x", tont_ptr->policy);
		omci_adpt_set_commit_attriubte("GPON_TCONT", "Policy", tempBuffer);
#else
		/*See CFG Manager function gpon_execute(), Node (GPON_TCONT) do nothing!*/
#endif
		//upstream priority queue QOS Polcy Set
		ret=setQOSPolicy(tont_ptr->allocId ,tont_ptr->policy);
		if(ret != 0)
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setTcontPolicyValue: faile\n");
	}
	else
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"[%s] return OMCI_PARAM_ERROR, QoSConfFlex=0x%x\n",__FUNCTION__,QosConfFlex);
		return OMCI_PARAM_ERROR;
	}

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s] return success! policy=%d\n",__FUNCTION__,tont_ptr->policy);
	return 0;
}

int omci_me_gem_ctp_create_op(management_entry_ptr me_entry, omci_me_info_ptr me_info)
{
    omci_gem_port_ctp_ptr gem_ctp_ptr=NULL;
    gem_ctp_ptr = (omci_gem_port_ctp_ptr)me_info->attributes;

    if(gem_ctp_ptr->PriorityQueuePointerDown > DW_PRIORITY_QUEUE_TATOL_NUM){
        omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] create PriorityQueuePointerDown is not exist set to default 0\n",__FUNCTION__,__LINE__);
        gem_ctp_ptr->PriorityQueuePointerDown = 0;
    }
    return omci_me_gem_ctp_set_op(me_entry,me_info);
}
int omci_me_gem_ctp_delete_op(management_entry_ptr me_entry, omci_me_info_ptr me_info)
{	
	omci_gem_port_ctp_ptr gem_ctp_ptr=NULL;
	omci_me_info_t me_info_buf={0};

	if(me_info==NULL)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d] input paramter pointer is NULL\n",__FUNCTION__,__LINE__);
		return -1;
	}

	me_info_buf.class_id = OMCI_CLASS_ID_GEM_PORT_CTP;
	me_info_buf.inst_id = me_info->inst_id; 	
	if(omci_attr_get_all_data_except_table_attr(&me_info_buf) != 0){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]get data failed.\n",__FUNCTION__,__LINE__);
       	return -1;		
	}

	gem_ctp_ptr = (omci_gem_port_ctp_ptr)me_info_buf.attributes;
	return omciDelQueueMappingRule(gem_ctp_ptr);
}

int omci_me_gem_ctp_set_op(management_entry_ptr me_entry, omci_me_info_ptr me_info)
{
	int ret=0;
	omci_gem_port_ctp_ptr gem_ctp_ptr=NULL;

	if(me_info==NULL || me_info->attributes == NULL)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d] input paramter pointer is NULL\n",__FUNCTION__,__LINE__);
		return -1;
	}
	
	ret = omci_me_general_set_op(me_entry,me_info);
	if(ret != OMCI_CMD_SUCCESS)
	{	
		omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d] omci_me_general_set_op return ret=%d\n",__FUNCTION__,__LINE__,ret);
		return ret;
	}

	gem_ctp_ptr = (omci_gem_port_ctp_ptr)me_info->attributes;

	if(me_info->mask & 0xe80){
		ret= omciAddQueueMappingRule(gem_ctp_ptr);
		omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d] omciAddQueueMappingRule, ret=%d\n",__FUNCTION__,__LINE__,ret);
		if(ret != 0)
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] omciAddQueueMappingRule fail!\n",__FUNCTION__,__LINE__);
	}

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]: return ret=%d\n",__FUNCTION__,__LINE__,ret);
	return ret;
}

int getEncryptionStateValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	uint16_t gemPortId = 0;
	uint32_t encryState = 0;
	struct XMCS_GemPortInfo_S *gponGemInfo;
	int i;
	omci_gem_port_ctp_ptr gem_ctp_ptr=NULL;

	gponGemInfo = malloc(sizeof(struct XMCS_GemPortInfo_S));	
	if(NULL == gponGemInfo){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "func:%s line:%d kzalloc fail\n",__FUNCTION__,__LINE__);
		return -1;
	}
	memset(gponGemInfo, 0, sizeof(struct XMCS_GemPortInfo_S)) ;

	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		free(gponGemInfo);
		return -1;
	}
	gem_ctp_ptr	= (omci_gem_port_ctp_ptr)(me_info->attributes);
	gemPortId = gem_ctp_ptr->portId;
		
	if(gponmgr_lib_get_gemport(gponGemInfo) != 0)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] gponmgr_lib_get_gemport return fail!\n",__FUNCTION__);
		free(gponGemInfo);
		return -1;
	}
	for(i=0 ; i<gponGemInfo->entryNum ; i++) 
	{
		if (gponGemInfo->info[i].gemPortId == gemPortId)
		{
			encryState = gponGemInfo->info[i].enMode;
		}
	}
	gem_ctp_ptr->encryptionState = (uint8_t)encryState;

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s] return success! encryptionState=%d\n",__FUNCTION__,gem_ctp_ptr->encryptionState);
	free(gponGemInfo);
	return 0;
}

int setEncryptionKeyRingValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{   
    struct XMCS_GemPortCreate_S gponGemCreate = {0};
	omci_gem_port_ctp_ptr gem_ctp_ptr=NULL;
	omci_t_cont_ptr  tcont_ptr=NULL;
	omci_me_info_t me_info_buf={0};

	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}
	
	if(omci_onu_cap_g.linkMode == XMCS_IF_WAN_DETECT_MODE_GPON || omci_onu_cap_g.linkMode == XMCS_IF_WAN_DETECT_MODE_GPON_SYM || omci_onu_cap_g.linkMode == XMCS_IF_WAN_DETECT_MODE_AUTO){	
		omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s] no need to process in GPON\n",__FUNCTION__);
		return 0;
	}

	gem_ctp_ptr	= (omci_gem_port_ctp_ptr)(me_info->attributes);
    
    /*mask is 1, get gemport id*/
	gponGemCreate.gemPortId = gem_ctp_ptr->portId;
    
    /*get allocId*/
	me_info_buf.class_id = OMCI_CLASS_ID_T_CONT;
	me_info_buf.inst_id = gem_ctp_ptr->tcontPointer;
	
	/*the inst_id of tcont should range from 0x8000 to 0x801f,as we just support 32 tconts currently*/
	if((me_info_buf.inst_id < T_CONT_INST_START_ID) || 
		(me_info_buf.inst_id > (T_CONT_INST_START_ID + T_CONT_TOTAL_NUM - 1)))
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d] tcont inst_id == 0\n",__FUNCTION__,__LINE__);
		return 0;
	}
	else if(omci_attr_get_all_data_except_table_attr(&me_info_buf) != 0){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d] get attribute data fail\n",__FUNCTION__,__LINE__);
		return -1;
	}
	tcont_ptr = (omci_t_cont_ptr)(me_info_buf.attributes);
	gponGemCreate.allocId = tcont_ptr->allocId;
	gponGemCreate.gemEncrypt = gem_ctp_ptr->encryptionKeyRing;
	gponmgr_lib_set_xgem_encrypt(gponGemCreate);

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s] return success!\n",__FUNCTION__);
	return 0;
}

int getMaxQueueSizeValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	uint16_t meId = 0;
	uint8_t queueId = 0;
	omci_priority_queue_ptr pq_ptr = NULL;
	
	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}
	pq_ptr = (omci_priority_queue_ptr)(me_info->attributes);
	
	meId = pq_ptr->meId;
	if(meId >=  T_CONT_INST_START_ID)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] meId(%d) >=  0x8000\n",__FUNCTION__,meId);
		if(bbf247_enable)
		{
			return 0;
		}
		else
		{
			return -1;
		}
	}
	
	//downstream priority queue
	/*wait for switch api*/
	queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_UIN_PORT);			
	pq_ptr->maxQueueSize = macMT7530GetMaximumQueueSize(queueId);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]:  return maxQueueSize = %hu\n",__FUNCTION__,__LINE__,pq_ptr->maxQueueSize);		
	return 0;
}

int getAllocQueueSizeValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	uint16_t meId = 0;
	uint8_t queueId = 0;
	omci_priority_queue_ptr pq_ptr = NULL;
	
	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}
	pq_ptr = (omci_priority_queue_ptr)(me_info->attributes);
	
	meId = pq_ptr->meId;
	if(meId >=	T_CONT_INST_START_ID)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] meId(%d) >=  0x8000\n",__FUNCTION__,meId);
		return -1;
	}

	queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_UIN_PORT); 		
	pq_ptr->allocatedQueueSize= macMT7530GetAllocatedQueueSize(queueId);
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]:  return 0, allocatedQueueSize = %hu\n",__FUNCTION__,__LINE__,pq_ptr->allocatedQueueSize); 	
	return 0;
}

int setAllocQueueSizeValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	uint16_t meId = 0;
	uint8_t queueId = 0;
	int ret=0;
	omci_priority_queue_ptr pq_ptr = NULL;
	
	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}
	pq_ptr = (omci_priority_queue_ptr)(me_info->attributes);
	
	meId = pq_ptr->meId;
	if(meId >=	T_CONT_INST_START_ID)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] meId(%d) >=  0x8000\n",__FUNCTION__,meId);
		return -1;
	}

	queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_UIN_PORT); 		
	ret = macMT7530SetAllocatedQueueSize(pq_ptr->allocatedQueueSize, queueId);
	if(ret != 0){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: macMT7530SetAllocatedQueueSize return fail, ret=%d 0x8000\n",__FUNCTION__,__LINE__,ret);
		return -1;
	}

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]:  return 0, allocatedQueueSize = %hu\n",__FUNCTION__,__LINE__,pq_ptr->allocatedQueueSize); 	
	return 0;
}

int setRelatePortValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	uint16_t qosCfg = 0;
	uint16_t port = 0;
	uint16_t priority = 0;
	uint32_t relatedPort = 0;
	uint16_t meId = 0;
	uint16_t trafficSchedPoint =  0;
	uint16_t portOld = 0;
	uint32_t valueTmp = 0;
	int ret =  0;

	omci_priority_queue_ptr pq_ptr = NULL;
	omci_me_info_t me_info_buf = {0};
	omci_onu2_g_ptr onu2_g_ptr = NULL;
	
	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}
	
	pq_ptr = (omci_priority_queue_ptr)(me_info->attributes);
	meId = pq_ptr->meId;
	trafficSchedPoint = pq_ptr->trafficSchedulerPointer;
	relatedPort = pq_ptr->relatedPort;

	me_info_buf.class_id = OMCI_CLASS_ID_ONU2_G;
	me_info_buf.inst_id = 0;
	if(omci_attr_get_all_data_except_table_attr(&me_info_buf) != 0){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: get attribute fail.\n",__FILE__, __LINE__);
		return -1;
	}

	onu2_g_ptr = (omci_onu2_g_ptr)(me_info_buf.attributes);
	qosCfg = onu2_g_ptr->qosCfgFlexibility;
	
	//bit 1: priority queue ME's port field of related port attribute is read-write and can point to any T-CONT or UNI port in the same slot;
	//bit 2: priority queue ME's traffic scheduler pointer is permitted to refer to any other traffic scheduler in the same slot
	//bit 3: traffic scheduler ME's T-CONT pointer is read-write
	//bit 4: traffic scheduler ME's policy attribute is read-write
	//bit 5: T-CONT ME's policy attribute is read-write
	//bit 6: Priority queue ME's Priority field of related port attribute is read-write
	//others: reserved

	if(((qosCfg & 0x01) != 0) && ((qosCfg & 0x20) != 0))
	{
		if(trafficSchedPoint == 0)//traffic scheduler pointer is null
		{
			port = (uint16_t)((relatedPort >> 16) & 0x00ff);
			priority = (uint16_t)(relatedPort & 0x00ff);
			
			valueTmp =	pq_ptr->relatedPort;
			portOld = (uint16_t)((valueTmp >> 16) & 0x00ff);
			omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d]: port = 0x%x, portOld = 0x%x, priority = 0x%x\n",__FUNCTION__,__LINE__, port, portOld,priority);
			if(meId < T_CONT_INST_START_ID)
			{
				uint16_t queueId = 0;
				uint8_t weight = 0;
				//downstream priority queue
				/*wait for switch api*/ 	
				queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_UIN_PORT);		
				macMT7530SetQueuePriority(priority, queueId);	
				weight = macMT7530GetWeight(queueId, portOld);	
				if(portOld != port)
				{
	//				macMT7530CleanWeight(queueId, port);	//no such api now
					ret = macMT7530SetWeight(weight, queueId, port);
				}
				if(ret != 0)
				{
					omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"[%s][%d]: set relateport fail!\n",__FUNCTION__,__LINE__); 			
					return -1;
				}
			}
			else
			{
				//upstream priority queue
				//wait for pon mac api
					
			}			
		}
		else
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"[%s][%d]: trafficSchedPoint is not null, relateport is igored!\n",__FUNCTION__,__LINE__); 				
			return OMCI_PARAM_ERROR;		
		}
	}
	else
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"[%s][%d]: qosCfg is 0x%x, can't not set relateport!\n",__FUNCTION__,__LINE__,qosCfg); 				
		return OMCI_PARAM_ERROR;
	}

	
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d]: return 0. related port = 0x%x\n",__FUNCTION__,__LINE__,pq_ptr->relatedPort);
	return ret;
}

int setTrafficSchedPointValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	uint16_t meIdT_CONT = 0;
	uint32_t relatePort = 0;
	uint16_t trafficSchedId = 0;
	uint16_t meIdT_CONT_tmp = 0;
	//uint16_t qosCfg = 0;
	uint16_t meId = 0;
	
	omci_priority_queue_ptr pq_ptr = NULL;
	omci_me_info_t me_info_buf = {0};
	//omci_onu2_g_ptr onu2_g_ptr = NULL;
	omci_traffic_scheduler_ptr traffic_sch_ptr = NULL;
	
	omci_gem_port_ctp_ptr gem_ctp_ptr=NULL;
	int inst_count=0;
	int i=0;
	uint16_t inst_list[MAX_INST_COUNT]={0};
	int result = 0;

	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}
	
	pq_ptr = (omci_priority_queue_ptr)(me_info->attributes);
	meId = pq_ptr->meId;

	if(meId >= T_CONT_INST_START_ID)
	{
		//upstream priority queue
		trafficSchedId = pq_ptr->trafficSchedulerPointer;
/*		me_info_buf.class_id = OMCI_CLASS_ID_ONU2_G;
		me_info_buf.inst_id = 0;
		if(omci_attr_get_all_data_except_table_attr(&me_info_buf) != 0){
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: get attribute fail.\n",__FILE__, __LINE__);
			return -1;
		}
		
		onu2_g_ptr = (omci_onu2_g_ptr)(me_info_buf.attributes);
		qosCfg = onu2_g_ptr->qosCfgFlexibility;
		omcidbgPrintf(OMCI_DEBUG_LEVEL_NO_MSG,"[%s][%d] qosCfg=0x%x,trafficSchedId=%0x%x\n",__FILE__, __LINE__,qosCfg,trafficSchedId);

		if(qosCfg & 0x02)
		{
		//NOTE: initial trafficSchduler Pointer is NULL! if forbit set trafficSchduler Pointer, WRR and SP+WRR will fail!
*/
			if(trafficSchedId != 0)
			{
				me_info_buf.class_id = OMCI_CLASS_ID_TRAFFIC_SCHEDULER;
				me_info_buf.inst_id = pq_ptr->trafficSchedulerPointer;
				if(omci_attr_get_all_data_except_table_attr(&me_info_buf) != 0){
					omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: get attribute fail.\n",__FILE__, __LINE__);
					return -1;
				}
				traffic_sch_ptr = (omci_traffic_scheduler_ptr)(me_info_buf.attributes);
				meIdT_CONT_tmp = traffic_sch_ptr->tcontPointer;				
				
				relatePort = pq_ptr->relatedPort;
				meIdT_CONT = ((relatePort>>16)&0xffff);

				if(meIdT_CONT !=  meIdT_CONT_tmp)
				{
					omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"[%s][%d]: tcont mismatch, reject the operation\n",__FILE__, __LINE__);
					return OMCI_PARAM_ERROR;
				}
			}else if(trafficSchedId == 0){

 				if(omci_lib_get_inst_count_by_classid(OMCI_CLASS_ID_GEM_PORT_CTP,&inst_count) == -1){
	    			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: omci_lib_get_inst_count_by_classid fail!\n",__FUNCTION__,__LINE__);
					return -1;
				}
				if (omci_lib_get_inst_list_by_classid(OMCI_CLASS_ID_GEM_PORT_CTP,inst_list,MAX_INST_COUNT) == -1){
					omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: omci_lib_get_inst_list_by_classid fail!\n",__FUNCTION__,__LINE__);
					return -1;
				}
				for(i=0; i< inst_count; i++){
					
					me_info_buf.class_id = OMCI_CLASS_ID_GEM_PORT_CTP;
					me_info_buf.inst_id= inst_list[i];
					if(omci_attr_get_all_data_except_table_attr(&me_info_buf) == 0){
						gem_ctp_ptr = (omci_gem_port_ctp_ptr)(me_info_buf.attributes);
						if(gem_ctp_ptr != NULL){
							result = omciAddQueueMappingRule(gem_ctp_ptr);
							if(result != 0){
								omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: ---result =%d fail.\n",__FILE__, __LINE__,result);
							}
						}
					}
				}
					
		}
	}
	else
	{
		//downstream priority queue, reject the operation.
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"[%s][%d]: downstream priority queue, reject the operation,meId=0x%x\n",__FILE__, __LINE__,meId);			
		return OMCI_PARAM_ERROR;	
	}
	
	return 0;
}

int getWeightValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	uint16_t meId= 0;
	uint8_t queueId = 0;
	uint8_t weight = 1;
	uint32_t relatePort = 0;
	uint8_t qosChannel = 0;
	uint8_t qosType = 0;
	uint8_t ponWeight[MAX_NUM_OF_QUEUE_PER_TCONT] = {0};
	int ret = OMCI_GET_NO_VALUE;
	omci_priority_queue_ptr pq_ptr = NULL;
	omci_me_info_t me_info_tcont_buf={0};
	omci_t_cont_ptr tcont_ptr = NULL;

	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}
	pq_ptr = (omci_priority_queue_ptr)(me_info->attributes);

	meId = pq_ptr->meId;
	relatePort =  pq_ptr->relatedPort;
	if(meId < T_CONT_INST_START_ID)
	{
		uint8_t port = 0;
		//downstream priority queue
		/*wait for switch api*/	
		queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_UIN_PORT);		
		port = (uint8_t)((relatePort >> 16) & 0x00ff);
		weight = macMT7530GetWeight(queueId, port);		
		omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "\r\n getWeightValue: macMT7530GetWeight weight = %u\r\n",weight); 	
		pq_ptr->weight = weight;
	}
	else
	{
		//upstream priority queue
		//wait for pon mac api
		queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_TCONT);		

		me_info_tcont_buf.class_id = OMCI_CLASS_ID_T_CONT;
		me_info_tcont_buf.inst_id = (relatePort >> 16) & 0x00ff;
		if(omci_attr_get_all_data_except_table_attr(&me_info_tcont_buf) != 0){
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: get attribute fail.\n",__FILE__, __LINE__);
			return -1;
		}

		tcont_ptr = (omci_t_cont_ptr)(me_info_tcont_buf.attributes);
		ret = getPonMacQOSParam(tcont_ptr->allocId, &qosChannel, &qosType, ponWeight);
		if(ret != 0)
		{		
			omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN,"getWeightValue: getPonMacQOSParam fail!\n");
			return 0;
		}
		weight = ponWeight[queueId];
		pq_ptr->weight = weight;	
	}		

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d]: return ret=%d, weigt=%d\n",__FILE__, __LINE__,ret,pq_ptr->weight); 		
	return ret;	
}
int setWeightValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	uint16_t meId= 0;
	uint8_t queueId = 0;
	int ret = 0;
	uint8_t weight = 0;
	uint32_t relatePort = 0;
	uint8_t tcontId = 0;
	uint8_t qosType = 0;
	uint8_t qosChannel = 0;
	uint8_t ponWeight[MAX_NUM_OF_QUEUE_PER_TCONT] = {0};
	omci_priority_queue_ptr pq_ptr = NULL;
	omci_me_info_t me_info_buf={0};
	omci_traffic_scheduler_ptr ts_ptr=NULL;
	omci_onu2_g_ptr onu2_g_ptr = NULL;
	omci_t_cont_ptr tont_ptr=NULL;
	uint16_t qosCfg = 0;
	uint8_t ts_qosType = 0;
	uint8_t tc_qosType = 0;
	uint8_t ts_tcontId = 0;
	
	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}
	pq_ptr = (omci_priority_queue_ptr)(me_info->attributes);

	meId = pq_ptr->meId;
	relatePort = pq_ptr->relatedPort;
	weight = pq_ptr->weight;
	
	if(meId < T_CONT_INST_START_ID)
	{
		uint8_t port = 0;
		//downstream priority queue
		/*wait for switch api*/
		queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_UIN_PORT);		
		port = (uint8_t)((relatePort >> 16) & 0x00ff);		
		omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"setWeightValue: weight=%d, queueId=%d, port=%d!\n",weight, queueId, port);
		ret = macMT7530SetWeight(weight, queueId, port);
		if(ret != 0)
		{		
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setWeightValue: getPonMacQOSParam fail!\n");
			return ret;
		}
	}
	else
	{
		//upstream priority queue
		//wait for pon mac api
		me_info_buf.class_id = OMCI_CLASS_ID_T_CONT;
		me_info_buf.inst_id = (uint16_t)(relatePort >> 16);
		if(omci_attr_get_all_data_except_table_attr(&me_info_buf) == -1)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] [%d]: get attribute fail, classId = %d, inst_id = %x\n",__FILE__, __LINE__,me_info_buf.class_id , me_info_buf.inst_id);
			return -1;
		}

		tont_ptr = (omci_t_cont_ptr)(me_info_buf.attributes);
		queueId = (uint8_t)((meId & 0x00ff)  % NUM_OF_QUEUE_PER_TCONT);
		tcontId = (uint8_t)tont_ptr->meId;

		ret = getPonMacQOSParam(tont_ptr->allocId, &qosChannel, &qosType, ponWeight);
		if(ret != 0)
		{		
			omcidbgPrintf(OMCI_DEBUG_LEVEL_WARN,"setWeightValue: getPonMacQOSParam fail!\n");
			return 0;
		}
		ponWeight[queueId] = weight;

		me_info_buf.class_id = OMCI_CLASS_ID_ONU2_G;
		me_info_buf.inst_id = 0;
		if(omci_attr_get_all_data_except_table_attr(&me_info_buf) != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] [%d]: get attribute fail, classId = %d, inst_id = %x\n",__FILE__, __LINE__,me_info_buf.class_id , me_info_buf.inst_id);
			return -1;
		}

		onu2_g_ptr = (omci_onu2_g_ptr)(me_info_buf.attributes);
		qosCfg = onu2_g_ptr->qosCfgFlexibility;

		if(0 == pq_ptr->trafficSchedulerPointer)
		{
			tc_qosType = tont_ptr->policy;
			omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d]: get value weight = %d, tc_qosType = %d, qosCfg = %x\n",__FILE__, __LINE__,pq_ptr->weight,tc_qosType,qosCfg);
			if((0 == weight) && (TCONT_POLICY_SP == tc_qosType) && (qosCfg & 0x0010))
			{
				 switch(queueId)
				 {
					case 2:
						//SPWRR2: q7>q6>q5>q4>q3>q2>q1:q0, q1:q0 = w1:w0
						qosType = XMCS_IF_QOS_TYPE_SPWRR2;
						break;
					case 3:
						qosType = XMCS_IF_QOS_TYPE_SPWRR3;
						break;
					case 4:
						qosType = XMCS_IF_QOS_TYPE_SPWRR4;
						break;
					case 5:
						qosType = XMCS_IF_QOS_TYPE_SPWRR5;
						break;
					case 6:
						qosType = XMCS_IF_QOS_TYPE_SPWRR6;
						break;
					case 7:
						qosType = XMCS_IF_QOS_TYPE_SPWRR7;
						break;
					default:
						break;
				}
			}

		}
		else
		{
			me_info_buf.class_id = OMCI_CLASS_ID_TRAFFIC_SCHEDULER;
			me_info_buf.inst_id = pq_ptr->trafficSchedulerPointer;
			if(omci_attr_get_all_data_except_table_attr(&me_info_buf) == -1)
			{
				omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] [%d]: get attribute fail, classId = %d, inst_id = %x\n",__FILE__, __LINE__,me_info_buf.class_id , me_info_buf.inst_id);
				return -1;
			}

			ts_ptr = (omci_traffic_scheduler_ptr)(me_info_buf.attributes);
			ts_qosType = ts_ptr->policy;
			ts_tcontId = (uint8_t)(ts_ptr->tcontPointer & 0x00ff);

			if((qosCfg & 0x0008) && (TCONT_POLICY_WRR == ts_qosType) && (tcontId == ts_tcontId))
			{
				if(NUM_OF_QUEUE_PER_TCONT-1 == queueId)
				{
					qosType = XMCS_IF_QOS_TYPE_WRR;
				}

				if((weight > 0x64) && (weight <= 0xff))
				{
					//HW olt by set priority queue weight value 0xfe to disable queue tx
					ponWeight[queueId] = 0;
				}
			}
		}

		ret = setPonMacQOSParam(qosChannel, qosType, ponWeight);
		omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"setWeightValue==qosChannel=%d,qosType=%d, ponWeight=%d %d %d %d %d %d %d %d; ret=%d\n",
			qosChannel,qosType,ponWeight[7],ponWeight[6],ponWeight[5],ponWeight[4],ponWeight[3],ponWeight[2],ponWeight[1],ponWeight[0],ret);

		if(ret != 0)
		{		
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setWeightValue: setPonMacQOSParam fail!\n");
			return ret;
		}				
	}	

	return 0;	
}
int getBackPressureOperatetValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	uint16_t meId= 0;
	int ret = OMCI_GET_NO_VALUE;
	omci_priority_queue_ptr pq_ptr = NULL;
	
	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}
	pq_ptr = (omci_priority_queue_ptr)(me_info->attributes);
	
	meId = pq_ptr->meId;

	if(meId < T_CONT_INST_START_ID)
	{
		uint32_t relatePort = 0;
		uint8_t queueId = 0;
		uint16_t enableValue = 0;
		backPressure_t backPressure={0};
		uint8_t port = 0;

		//downstream priority queue
		/*wait for switch api*/ 
		relatePort = pq_ptr->relatedPort;
		port = (uint8_t)((relatePort >> 16) & 0x00ff);
		queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_UIN_PORT); 			
		ret = macMT7530GetBackPressure((mt7530_switch_api_backPressure_t *)(&backPressure), queueId, port);
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"getBackPressureOperatetValue: macMT7530GetBackPressure fail!\n");
			return ret;
		}
		enableValue = backPressure.Enable ? 0 : 1;	
		pq_ptr->backPressureOperation = enableValue;

	}
	else
	{
		//upstream priority queue
		//wait for pon mac api
		#if 0
		queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_TCONT);				
		ret = ponMacGetBackPressure(&backPressure, queueId);	
		if(ret != 0)
		{
				omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"getBackPressureOperatetValue: ponMacGetBackPressure fail!\n");
			return ret;
		}
		enableValue = backPressure.Enable;
		pq_ptr->backPressureOperation = enableValue;
		#endif
	}
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d]: return ret=%d, backPressureOperation=%d\n",__FILE__, __LINE__,ret,pq_ptr->backPressureOperation);
	return ret;
}

int setBackPressureOperatetValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	uint16_t meId= 0;
	int ret = 0;
	omci_priority_queue_ptr pq_ptr = NULL;
	
	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}
	pq_ptr = (omci_priority_queue_ptr)(me_info->attributes);
	
	meId = pq_ptr->meId;

	if(meId < T_CONT_INST_START_ID)
	{
		uint8_t queueId = 0;
		uint16_t enableValue = 0;
		backPressure_t backPressure={0};
		uint32_t relatePort = 0;
		uint8_t port = 0;

		//downstream priority queue
		/*wait for switch api*/ 
		relatePort = pq_ptr->relatedPort;
		port = (uint8_t)((relatePort >> 16) & 0x00ff);
		queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_UIN_PORT); 			
		ret = macMT7530GetBackPressure((mt7530_switch_api_backPressure_t *)(&backPressure), queueId, port);
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setBackPressureOperatetValue: macMT7530GetBackPressure fail!\n");
			return ret;
		}

		enableValue = pq_ptr->backPressureOperation;
		backPressure.Enable = enableValue ? 0 : 1;
		ret = macMT7530SetBackPressure((mt7530_switch_api_backPressure_t *)(&backPressure), queueId, port);
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setBackPressureOperatetValue: macMT7530SetBackPressure fail!\n");
			return ret;
		}
	}
	else
	{
		//upstream priority queue
		//wait for pon mac api
		#if 0
		queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_TCONT);				
		ret = ponMacGetBackPressure(&backPressure, queueId);
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setBackPressureOperatetValue: ponMacGetBackPressure fail!\n");
			return ret;
		}
		
		enableValue = pq_ptr->backPressureOperation;
		backPressure.Enable = enableValue;
		ret = ponMacSetBackPressure(&backPressure, queueId);
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setBackPressureOperatetValue: ponMacSetBackPressure fail!\n");
			return ret;
		}
		#endif
	}
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d]: return 0, backPressureOperation=%d\n",__FILE__, __LINE__,pq_ptr->backPressureOperation);
	return ret;
}

int getBackPressureTimeValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	uint16_t meId= 0;
	int ret = OMCI_GET_NO_VALUE;
	omci_priority_queue_ptr pq_ptr = NULL;
	
	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}
	pq_ptr = (omci_priority_queue_ptr)(me_info->attributes);
	
	meId = pq_ptr->meId;

	if(meId < T_CONT_INST_START_ID)
	{
		uint8_t queueId = 0;
		backPressure_t backPressure={0};
		uint32_t relatePort = 0;
		uint8_t port = 0;
		uint32_t time = 0;

		//downstream priority queue
		/*wait for switch api*/ 
		relatePort = pq_ptr->relatedPort;
		port = (uint8_t)((relatePort >> 16) & 0x00ff);
		queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_UIN_PORT); 			
		ret = macMT7530GetBackPressure((mt7530_switch_api_backPressure_t *)(&backPressure), queueId, port);
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"getBackPressureOperatetValue: macMT7530GetBackPressure fail!\n");
			return ret;
		}
		time = backPressure.time;
		pq_ptr->backPressureTime = time;
	}
	else
	{
		//upstream priority queue
		//wait for pon mac api
		#if 0
		queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_TCONT);						
		ret = ponMacGetBackPressure(&backPressure, queueId);
		if(ret != 0)
		{
				omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"getBackPressureOperatetValue: ponMacGetBackPressure fail!\n");
			return ret;
		}
		time = backPressure.time;	
		pq_ptr->backPressureTime = time;
		#endif
	}
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d]: return ret=%d, backPressureTime=%u\n",__FILE__, __LINE__,ret,pq_ptr->backPressureTime);
	return ret;
}

int setBackPressureTimeValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	uint16_t meId= 0;
	int ret = 0;
	omci_priority_queue_ptr pq_ptr = NULL;
	
	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}
	pq_ptr = (omci_priority_queue_ptr)(me_info->attributes);
	
	meId = pq_ptr->meId;

	if(meId < T_CONT_INST_START_ID)
	{
		uint8_t queueId = 0;
		backPressure_t backPressure={0};
		uint32_t relatePort = 0;
		uint8_t port = 0;
		uint32_t time = 0;

		//downstream priority queue
		/*wait for switch api*/ 
		relatePort = pq_ptr->relatedPort;
		port = (uint8_t)((relatePort >> 16) & 0x00ff);
		queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_UIN_PORT); 			
		ret = macMT7530GetBackPressure((mt7530_switch_api_backPressure_t *)(&backPressure), queueId, port);
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setBackPressureTimeValue: macMT7530GetBackPressure fail!\n");
			return ret;
		}

		time = pq_ptr->backPressureTime;
		backPressure.time = time;
		ret = macMT7530SetBackPressure((mt7530_switch_api_backPressure_t *)(&backPressure), queueId, port);
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setBackPressureTimeValue: macMT7530SetBackPressure fail!\n");
			return ret;
		}
	}
	else
	{
		//upstream priority queue
		//wait for pon mac api
		#if 0
		queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_TCONT);										
		ret = ponMacGetBackPressure(&backPressure, queueId);
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setBackPressureTimeValue: ponMacGetBackPressure fail!\n");
			return ret;
		}

		time = pq_ptr->backPressureTime;
		backPressure.time = time;
		ret = ponMacSetBackPressure(&backPressure, queueId);
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setBackPressureTimeValue: ponMacSetBackPressure fail!\n");
			return ret;
		}	
		#endif
	}
	
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d]: return 0, backPressureTime=%u\n",__FILE__, __LINE__,pq_ptr->backPressureTime);
	return ret;
}

int getBackPressureOccurThredValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	uint16_t meId= 0;
	int ret = OMCI_GET_NO_VALUE;
	omci_priority_queue_ptr pq_ptr = NULL;
	
	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}
	pq_ptr = (omci_priority_queue_ptr)(me_info->attributes);
	
	meId = pq_ptr->meId;

	if(meId < T_CONT_INST_START_ID)
	{
		uint8_t queueId = 0;
		backPressure_t backPressure={0};
		uint32_t relatePort = 0;
		uint8_t port = 0;
		uint16_t maxQueueThred = 0;
		//downstream priority queue
		/*wait for switch api*/ 
		relatePort = pq_ptr->relatedPort;
		port = (uint8_t)((relatePort >> 16) & 0x00ff);
		queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_UIN_PORT); 			
		ret = macMT7530GetBackPressure((mt7530_switch_api_backPressure_t *)(&backPressure), queueId, port);
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setBackPressureTimeValue: macMT7530GetBackPressure fail!\n");
			return ret;
		}
		maxQueueThred = backPressure.MaxQueueThreshold;
		pq_ptr->backPressOccurQueueThd = maxQueueThred;

	}
	else
	{
		//upstream priority queue
		//wait for pon mac api
		#if 0
		queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_TCONT);										
		ret = ponMacGetBackPressure(&backPressure, queueId);
		if(ret != 0)
		{
				omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"getBackPressureOccurThredValue: ponMacGetBackPressure fail!\n");
			return ret;
		}
		maxQueueThred = backPressure.MaxQueueThreshold;
		pq_ptr->backPressOccurQueueThd = maxQueueThred;
		#endif
	}
	
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d]: return ret=%d, backPressOccurQueueThd=%d\n",__FILE__, __LINE__,ret,pq_ptr->backPressOccurQueueThd);
	return ret;
}
int setBackPressureOccurThredValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	uint16_t meId= 0;
	int ret = 0;
	omci_priority_queue_ptr pq_ptr = NULL;
	
	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}
	pq_ptr = (omci_priority_queue_ptr)(me_info->attributes);
	
	meId = pq_ptr->meId;

	if(meId < T_CONT_INST_START_ID)
	{
		uint8_t queueId = 0;
		backPressure_t backPressure={0};
		uint32_t relatePort = 0;
		uint8_t port = 0;
		uint16_t maxQueueThred = 0;
		//downstream priority queue
		/*wait for switch api*/ 
		relatePort = pq_ptr->relatedPort;
		port = (uint8_t)((relatePort >> 16) & 0x00ff);
		queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_UIN_PORT); 			
		queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_UIN_PORT);										
		ret = macMT7530GetBackPressure((mt7530_switch_api_backPressure_t *)(&backPressure), queueId, port);
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setBackPressureOccurThredValue: macMT7530GetBackPressure fail!\n");
			return ret;
		}
			
		maxQueueThred = pq_ptr->backPressOccurQueueThd;
		backPressure.MaxQueueThreshold= maxQueueThred;
		ret = macMT7530SetBackPressure((mt7530_switch_api_backPressure_t *)(&backPressure), queueId, port);

		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setBackPressureOccurThredValue: macMT7530SetBackPressure fail!\n");
			return ret;
		}
	}
	else
	{
		//upstream priority queue
		//wait for pon mac api
		#if 0
		queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_TCONT);										
		ret = ponMacGetBackPressure(&backPressure, queueId);
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setBackPressureOccurThredValue: ponMacGetBackPressure fail!\n");
			return ret;
		}
			
		maxQueueThred = pq_ptr->backPressOccurQueueThd;
		backPressure.MaxQueueThreshold= maxQueueThred;
		ret = ponMacSetBackPressure(&backPressure, queueId);
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setBackPressureOccurThredValue: ponMacSetBackPressure fail!\n");
			return ret;
		}
		#endif
	}
	
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d]: return 0, backPressOccurQueueThd=%u\n",__FILE__, __LINE__,pq_ptr->backPressOccurQueueThd);
	return ret;
}

int getBackPressureClearThredValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	uint16_t meId= 0;
	int ret = OMCI_GET_NO_VALUE;
	omci_priority_queue_ptr pq_ptr = NULL;
	
	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}
	pq_ptr = (omci_priority_queue_ptr)(me_info->attributes);
	
	meId = pq_ptr->meId;

	if(meId < T_CONT_INST_START_ID)
	{
		uint8_t queueId = 0;
		backPressure_t backPressure={0};
		uint32_t relatePort = 0;
		uint8_t port = 0;
		uint16_t minQueueThred = 0;
		//downstream priority queue
		/*wait for switch api*/ 
		relatePort = pq_ptr->relatedPort;
		port = (uint8_t)((relatePort >> 16) & 0x00ff);
		queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_UIN_PORT); 			
		ret = macMT7530GetBackPressure((mt7530_switch_api_backPressure_t *)(&backPressure), queueId, port);
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setBackPressureTimeValue: macMT7530GetBackPressure fail!\n");
			return ret;
		}
		minQueueThred = backPressure.MinQueueThreshold;
		pq_ptr->backPressClearQueueThd= minQueueThred;

	}
	else
	{
		//upstream priority queue
		//wait for pon mac api
		#if 0
		queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_TCONT);										
		ret = ponMacGetBackPressure(&backPressure, queueId);
		if(ret != 0)
		{
				omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"getBackPressureOccurThredValue: ponMacGetBackPressure fail!\n");
			return ret;
		}
		minQueueThred = backPressure.MinQueueThreshold;
		pq_ptr->backPressClearQueueThd = minQueueThred;
		#endif
	}
	
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d]: return ret=%d, backPressClearQueueThd=%u\n",__FILE__, __LINE__,ret,pq_ptr->backPressClearQueueThd);
	return ret;
}
int setBackPressureClearThredValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	uint16_t meId= 0;
	int ret = 0;
	omci_priority_queue_ptr pq_ptr = NULL;
	
	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}
	pq_ptr = (omci_priority_queue_ptr)(me_info->attributes);
	
	meId = pq_ptr->meId;

	if(meId < T_CONT_INST_START_ID)
	{
		uint8_t queueId = 0;
		backPressure_t backPressure={0};
		uint32_t relatePort = 0;
		uint8_t port = 0;
		uint16_t maxQueueThred = 0;
		//downstream priority queue
		/*wait for switch api*/ 
		relatePort = pq_ptr->relatedPort;
		port = (uint8_t)((relatePort >> 16) & 0x00ff);
		queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_UIN_PORT); 			
		queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_UIN_PORT);										
		ret = macMT7530GetBackPressure((mt7530_switch_api_backPressure_t *)(&backPressure), queueId, port);
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setBackPressureOccurThredValue: macMT7530GetBackPressure fail!\n");
			return ret;
		}
			
		maxQueueThred = pq_ptr->backPressClearQueueThd;
		backPressure.MaxQueueThreshold= maxQueueThred;
		ret = macMT7530SetBackPressure((mt7530_switch_api_backPressure_t *)(&backPressure), queueId, port);

		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setBackPressureOccurThredValue: macMT7530SetBackPressure fail!\n");
			return ret;
		}
	}
	else
	{
		//upstream priority queue
		//wait for pon mac api
		#if 0
		queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_TCONT);										
		ret = ponMacGetBackPressure(&backPressure, queueId);
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setBackPressureOccurThredValue: ponMacGetBackPressure fail!\n");
			return ret;
		}
			
		maxQueueThred = pq_ptr->backPressClearQueueThd;
		backPressure.MaxQueueThreshold= maxQueueThred;
		ret = ponMacSetBackPressure(&backPressure, queueId);
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setBackPressureOccurThredValue: ponMacSetBackPressure fail!\n");
			return ret;
		}
		#endif
	}
	
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d]: return 0, backPressOccurQueueThd=%u\n",__FILE__, __LINE__,pq_ptr->backPressOccurQueueThd);
	return ret;
}

int getPacketDropThredValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	uint16_t meId= 0;
	int ret = OMCI_GET_NO_VALUE;
	omci_priority_queue_ptr pq_ptr = NULL;
	
	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}
	pq_ptr = (omci_priority_queue_ptr)(me_info->attributes);

	meId = pq_ptr->meId;

	if(meId < T_CONT_INST_START_ID)
	{
		uint8_t queueId = 0;
		dropPolicy_t dropPolicy={0};
		uint32_t relatePort = 0;
		uint8_t port = 0;
		uint16_t greenPacketDropQueueMaxThr = 0;
		uint16_t greenPacketDropQueueMinThr = 0;
		uint16_t yellowPacketDropQueueMaxThr = 0;
		uint16_t yellowPacketDropQueueMinThr = 0;
		//downstream priority queue
		/*wait for switch api*/	
		relatePort = pq_ptr->relatedPort;
		port = (uint8_t)((relatePort >> 16) & 0x00ff);	
		queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_UIN_PORT);		
		ret =  macMT7530GetDropPolicy(port, queueId, (mt7530_switch_DropPolicy_t *)(&dropPolicy));
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"getPacketDropThredValue: macMT7530GetDropPolicy fail!\n");
			return ret;
		}
		greenPacketDropQueueMaxThr = dropPolicy.greenPacketDropQueueMaxThr;
		greenPacketDropQueueMinThr = dropPolicy.greenPacketDropQueueMinThr;
		yellowPacketDropQueueMaxThr = dropPolicy.yellowPacketDropQueueMaxThr;
		yellowPacketDropQueueMinThr = dropPolicy.yellowPacketDropQueueMinThr;

		put16(pq_ptr->pktDropQueueThresholds,greenPacketDropQueueMaxThr);
		put16(&pq_ptr->pktDropQueueThresholds[2],greenPacketDropQueueMinThr);
		put16(&pq_ptr->pktDropQueueThresholds[4],yellowPacketDropQueueMaxThr);
		put16(&pq_ptr->pktDropQueueThresholds[6],yellowPacketDropQueueMinThr);

		omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d]:  pktDropQueueThresholds = %d,%d,%d,%d",__FILE__, __LINE__,
			greenPacketDropQueueMaxThr,greenPacketDropQueueMinThr,
			yellowPacketDropQueueMaxThr,yellowPacketDropQueueMinThr);		
	}
	else
	{
		//upstream priority queue
		//wait for pon mac api
#if 0	
		queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_TCONT);		
		ret = getPonMacCongestThreshold(queueId,  &congestQueueIdx, &greenPacketDropQueueMaxThr, 
			&greenPacketDropQueueMinThr, &yellowPacketDropQueueMaxThr, &yellowPacketDropQueueMinThr);
		
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"getPacketDropThredValue: getPonMacCongestThreshold fail!\n");
			return ret;
		}
		
		(pq_ptr->pktDropQueueThresholds)[0] = greenPacketDropQueueMaxThr;
		(pq_ptr->pktDropQueueThresholds)[1] = greenPacketDropQueueMinThr;
		(pq_ptr->pktDropQueueThresholds)[2] = yellowPacketDropQueueMaxThr;
		(pq_ptr->pktDropQueueThresholds)[3] = yellowPacketDropQueueMinThr;

#endif
	}
	
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d]: return ret=%d\n",__FILE__, __LINE__,ret);

	if(bbf247_enable)
	{
		return 0;
	}
	else
	{
		return -1;
	}
}

int omci_set_drop_preceduce_dei(int enable,int direction)
{
	int ret = 0;

	if(bbf247_enable){
		if(direction == DIR_UP){
			ret = bbf247_set_dei_qos_flag(BBF247_DIR_UP,enable);
		}
		else{
			ret = bbf247_set_dei_qos_flag(BBF247_DIR_DN,enable);
		}
	}else{
		ret = -1;
		omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d]: bbf247 is not loaded\n",__FUNCTION__,__LINE__);
		
	}
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d] deiQoS=%d  direciton = %d, ret = %d\n",
	__FUNCTION__,__LINE__,enable,direction,ret);

	return ret;	
}

/******************************************************************************
 Descriptor:	It's used to set GDM pcp mode
 Input Args:	- Pcp_mode:  0:FE_PCP_MODE_DISABLE, 1:FE_PCP_MODE_8B0D ,2:FE_PCP_MODE_7B1D , 4:FE_PCP_MODE_6B2D ,8:FE_PCP_MODE_5B3D
******************************************************************************/

int omci_set_gdm_pcp_mode(int PcpMode,int direction)
{
	int ret = 0;

	if(direction == DIR_UP){
		//lan
		ret |= fe_lib_set_gdma_pcp_coding(ECNT_FEMGR_GDM_SEL_GDMA1,ECNT_FEMGR_DIRECTON_RX,PcpMode);
		ret |= fe_lib_set_gdma_pcp_coding(ECNT_FEMGR_GDM_SEL_GDMA3,ECNT_FEMGR_DIRECTON_RX,PcpMode);
		ret |= fe_lib_set_gdma_pcp_coding(ECNT_FEMGR_GDM_SEL_GDMA4,ECNT_FEMGR_DIRECTON_RX,PcpMode);
		//wan
		ret |= fe_lib_set_gdma_pcp_coding(ECNT_FEMGR_GDM_SEL_GDMA2,ECNT_FEMGR_DIRECTON_TX,PcpMode);
	}
	else{
		//lan
		ret |= fe_lib_set_gdma_pcp_coding(ECNT_FEMGR_GDM_SEL_GDMA1,ECNT_FEMGR_DIRECTON_TX,PcpMode);
		ret |= fe_lib_set_gdma_pcp_coding(ECNT_FEMGR_GDM_SEL_GDMA3,ECNT_FEMGR_DIRECTON_TX,PcpMode);
		ret |= fe_lib_set_gdma_pcp_coding(ECNT_FEMGR_GDM_SEL_GDMA4,ECNT_FEMGR_DIRECTON_TX,PcpMode);
		//wan
		ret |= fe_lib_set_gdma_pcp_coding(ECNT_FEMGR_GDM_SEL_GDMA2,ECNT_FEMGR_DIRECTON_RX,PcpMode);
	}

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d] PcpMode=%d  direciton = %s, ret = %d\n",
	__FUNCTION__,__LINE__,PcpMode,direction == DIR_UP ? "UP" : "DN",ret);

	return ret;
}

void omci_clear_drop_preceduce_color_mark(void){
	omci_set_drop_preceduce_dei(0,DIR_UP);
	omci_set_drop_preceduce_dei(0,DIR_DOWN);
	omci_set_gdm_pcp_mode(0,DIR_UP);
	omci_set_gdm_pcp_mode(0,DIR_DOWN);
}

int setPacketDropThredValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	uint16_t meId= 0;
	int ret = 0;
	omci_priority_queue_ptr pq_ptr = NULL;
	
	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}
	pq_ptr = (omci_priority_queue_ptr)(me_info->attributes);

	meId = pq_ptr->meId;

	if(meId < T_CONT_INST_START_ID)
	{
		uint8_t queueId = 0;
		dropPolicy_t dropPolicy={0};
		uint32_t relatePort = 0;
		uint8_t port = 0;
		uint16_t greenPacketDropQueueMaxThr = 0;
		uint16_t greenPacketDropQueueMinThr = 0;
		uint16_t yellowPacketDropQueueMaxThr = 0;
		uint16_t yellowPacketDropQueueMinThr = 0;
		//downstream priority queue
		/*wait for switch api*/ 
		relatePort = pq_ptr->relatedPort;
		port = (uint8_t)((relatePort >> 16) & 0x00ff);	
		queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_UIN_PORT); 	
		ret =  macMT7530GetDropPolicy(port, queueId, (mt7530_switch_DropPolicy_t *)(&dropPolicy));
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setPacketDropThredValue: macMT7530GetBackPressure fail!\n");
			return ret;
		}
		
		greenPacketDropQueueMaxThr = get16(pq_ptr->pktDropQueueThresholds);
		greenPacketDropQueueMinThr = get16(&pq_ptr->pktDropQueueThresholds[2]);
		yellowPacketDropQueueMaxThr = get16(&pq_ptr->pktDropQueueThresholds[4]);
		yellowPacketDropQueueMinThr = get16(&pq_ptr->pktDropQueueThresholds[6]);		

		dropPolicy.greenPacketDropQueueMaxThr = greenPacketDropQueueMaxThr;
		dropPolicy.greenPacketDropQueueMinThr = greenPacketDropQueueMinThr;
		dropPolicy.yellowPacketDropQueueMaxThr = yellowPacketDropQueueMaxThr;
		dropPolicy.yellowPacketDropQueueMinThr = yellowPacketDropQueueMinThr;

		ret = macMT7530SetDropPolicy(port, queueId, (mt7530_switch_DropPolicy_t *)(&dropPolicy));		
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setPacketDropThredValue: macMT7530SetDropPolicy fail!\n");
			return ret;
		}

		omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d]:  pktDropQueueThresholds = %d,%d,%d,%d",__FILE__, __LINE__,
			greenPacketDropQueueMaxThr,greenPacketDropQueueMinThr,
			yellowPacketDropQueueMaxThr,yellowPacketDropQueueMinThr);	
omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"[%s][%d]:  pktDropQueueThresholds = %d,%d,%d,%d",__FILE__, __LINE__,
					greenPacketDropQueueMaxThr,greenPacketDropQueueMinThr,
					yellowPacketDropQueueMaxThr,yellowPacketDropQueueMinThr);

	}
	else
	{
		//upstream priority queue
		//wait for pon mac api
#if 0	
		queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_TCONT);		

		greenPacketDropQueueMaxThr = (pq_ptr->pktDropQueueThresholds)[0];
		greenPacketDropQueueMinThr = (pq_ptr->pktDropQueueThresholds)[1];
		yellowPacketDropQueueMaxThr = (pq_ptr->pktDropQueueThresholds)[2];
		yellowPacketDropQueueMinThr = (pq_ptr->pktDropQueueThresholds)[3];		

		ret = setCongestThredValue(queueId,  greenPacketDropQueueMaxThr, greenPacketDropQueueMaxThr, 
			greenPacketDropQueueMaxThr, yellowPacketDropQueueMinThr);
		
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setPacketDropThredValue: setCongestThredValue fail!\n");
			return ret;
		}

#endif
	}


	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d]: return 0\n",__FILE__, __LINE__);
	return ret;	

}
int getPonMacCongestDropProbality(uint8_t *geenDrop_p, uint8_t *yellowDrop_p)
{
	struct XMCS_TxQueueCongestion_S wanCongest;
	gponmgr_lib_get_congest_config(&wanCongest);
	*geenDrop_p = wanCongest.dropProbability.green;
	*yellowDrop_p = wanCongest.dropProbability.yellow;
	return 0;
}

int setCongestDropProbality(uint8_t greenDrop_p, uint8_t yellowDrop_p)
{
	struct XMCS_TxQueueCongestion_S wanCongest;

	wanCongest.dropProbability.green = greenDrop_p;
	wanCongest.dropProbability.yellow = yellowDrop_p;
	return (gponmgr_lib_set_congest_config(MASK_OF_CongestDropProbability,&wanCongest));
}

int getPacketDropMaxpValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	uint16_t meId= 0;
	int ret = OMCI_GET_NO_VALUE;
	uint8_t greenPacketDropMax_p = 0;
	uint8_t yellowPacketDropMax_p = 0;
	omci_priority_queue_ptr pq_ptr = NULL;
	
	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}
	pq_ptr = (omci_priority_queue_ptr)(me_info->attributes);

	meId = pq_ptr->meId;
	
	if(meId < T_CONT_INST_START_ID)
	{
		uint8_t queueId = 0;
		uint32_t relatePort = 0;
		uint8_t port = 0;
		dropPolicy_t dropPolicy={0};
		//downstream priority queue
		/*wait for switch api*/ 
		relatePort = pq_ptr->relatedPort;
		port = (uint8_t)((relatePort >> 16) & 0x00ff);	
		queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_UIN_PORT); 					
		ret =  macMT7530GetDropPolicy(port, queueId, (mt7530_switch_DropPolicy_t *)(&dropPolicy));
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"getPacketDropMaxpValue: macMT7530GetDropPolicy fail!\n");
			return ret;
		}
	
		(pq_ptr->pktDropMaxP)[0]= dropPolicy.greenPacketDropMax_p;
		(pq_ptr->pktDropMaxP)[1]= dropPolicy.yellowPacketDropMax_p;
	}
	else
	{
		//upstream priority queue
		//wait for pon mac api
	
		ret = getPonMacCongestDropProbality(&greenPacketDropMax_p, &yellowPacketDropMax_p); 
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"getPacketDropMaxpValue: getPonMacCongestDropProbality fail!\n");
			return ret;
		}
	
		(pq_ptr->pktDropMaxP)[0]= greenPacketDropMax_p;
		(pq_ptr->pktDropMaxP)[1]= yellowPacketDropMax_p;
	}

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d]: return ret=%d,greenPacketDropMax_p=%d,yellowPacketDropMax_p=%d\n",
		__FILE__, __LINE__,ret,(pq_ptr->pktDropMaxP)[0],(pq_ptr->pktDropMaxP)[1]);
	return ret;	
}
int setPacketDropMaxpValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	uint16_t meId= 0;
	int ret = 0;
	uint8_t greenPacketDropMax_p = 0;
	uint8_t yellowPacketDropMax_p = 0;
	omci_priority_queue_ptr pq_ptr = NULL;
	
	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}
	pq_ptr = (omci_priority_queue_ptr)(me_info->attributes);

	meId = pq_ptr->meId;
	
	if(meId < T_CONT_INST_START_ID)
	{
		uint8_t queueId = 0;
		uint32_t relatePort = 0;
		uint8_t port = 0;
		dropPolicy_t dropPolicy={0};
		//downstream priority queue
		/*wait for switch api*/ 
		relatePort = pq_ptr->relatedPort;
		port = (uint8_t)((relatePort >> 16) & 0x00ff);	
		queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_UIN_PORT); 					
		ret =  macMT7530GetDropPolicy(port, queueId, (mt7530_switch_DropPolicy_t *)(&dropPolicy));
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setPacketDropMaxpValue: macMT7530GetDropPolicy fail!\n");
			return ret;
		}
		
		dropPolicy.greenPacketDropMax_p = (pq_ptr->pktDropMaxP)[0];
		dropPolicy.yellowPacketDropMax_p = (pq_ptr->pktDropMaxP)[1];
		ret = macMT7530SetDropPolicy(port, queueId, (mt7530_switch_DropPolicy_t *)(&dropPolicy));		
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setPacketDropMaxpValue: macMT7530SetDropPolicy fail!\n");
			return ret;
		}
	}
	else
	{
		//upstream priority queue
		//wait for pon mac api
		greenPacketDropMax_p = (pq_ptr->pktDropMaxP)[0];
		yellowPacketDropMax_p = (pq_ptr->pktDropMaxP)[1];

		ret = setCongestDropProbality(greenPacketDropMax_p, yellowPacketDropMax_p);				
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setPacketDropMaxpValue: setCongestDropProbality fail!\n");
			return ret;
		}
	}

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d]: return 0,QueueDropWq[0](green)=%d,QueueDropWq[1](yellow)=%d\n",
		__FILE__, __LINE__,(pq_ptr->pktDropMaxP)[0],(pq_ptr->pktDropMaxP)[1]);
	return ret;	

}
int getQueueDropWqValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	uint16_t meId= 0;
	int ret = OMCI_GET_NO_VALUE;
	omci_priority_queue_ptr pq_ptr = NULL;
	
	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}
	pq_ptr = (omci_priority_queue_ptr)(me_info->attributes);

	meId = pq_ptr->meId;

	if(meId < T_CONT_INST_START_ID)
	{
		uint8_t queueId = 0;
		uint8_t queueDropW_q = 0;
		dropPolicy_t dropPolicy={0};
		uint32_t relatePort = 0;
		uint8_t port = 0;	
		//downstream priority queue
		/*wait for switch api*/ 
		relatePort = pq_ptr->relatedPort;
		port = (uint8_t)((relatePort >> 16) & 0x00ff);	
		queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_UIN_PORT); 									
		ret =  macMT7530GetDropPolicy(port, queueId, (mt7530_switch_DropPolicy_t *)(&dropPolicy));
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"getQueueDropWqValue: macMT7530GetDropPolicy fail!\n");
			return ret;
		}

		queueDropW_q = dropPolicy.QueueDropW_q;
		pq_ptr->queueDropWq = queueDropW_q;

	}
	else
	{
		//upstream priority queue
		//wait for pon mac api
#if 0	
		queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_TCONT);								
		ret =  ponMacGetDropPolicy(port, queueId, &dropPolicy);
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"getQueueDropWqValue: ponMacGetDropPolicy fail!\n");
			return ret;
		}
		
		queueDropW_q = dropPolicy.QueueDropW_q;
		pq_ptr->queueDropWq = queueDropW_q;
#endif		
	}
	
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d]: return ret=%d,queueDropWq=%d\n",__FILE__, __LINE__,ret,pq_ptr->queueDropWq);
	return ret;
}
int setQueueDropWqValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	uint16_t meId= 0;
	int ret = 0;
	omci_priority_queue_ptr pq_ptr = NULL;
	
	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}
	pq_ptr = (omci_priority_queue_ptr)(me_info->attributes);

	meId = pq_ptr->meId;

	if(meId < T_CONT_INST_START_ID)
	{
		uint8_t queueId = 0;
		uint8_t queueDropW_q = 0;
		dropPolicy_t dropPolicy={0};
		uint32_t relatePort = 0;
		uint8_t port = 0;	
		//downstream priority queue
		/*wait for switch api*/ 
		relatePort = pq_ptr->relatedPort;
		port = (uint8_t)((relatePort >> 16) & 0x00ff);	
		queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_UIN_PORT); 									
		ret =  macMT7530GetDropPolicy(port, queueId, (mt7530_switch_DropPolicy_t *)(&dropPolicy));
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setQueueDropWqValue: macMT7530GetDropPolicy fail!\n");
			return ret;
		}

		queueDropW_q = pq_ptr->queueDropWq;
		dropPolicy.QueueDropW_q= queueDropW_q;
		ret = macMT7530SetDropPolicy(port, queueId, (mt7530_switch_DropPolicy_t *)(&dropPolicy));		
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setQueueDropWqValue: macMT7530SetDropPolicy fail!\n");
			return ret;
		}
	}
	else
	{
		//upstream priority queue
		//wait for pon mac api
		#if 0
		queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_TCONT);												

		ret =  ponMacGetDropPolicy(port, queueId, &dropPolicy);
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setQueueDropWqValue: ponMacGetDropPolicy fail!\n");
			return ret;
		}

		queueDropW_q = pq_ptr->queueDropWq;
		dropPolicy.QueueDropW_q= queueDropW_q;
		ret =  ponMacSetDropPolicy(port, queueId, (mt7530_switch_DropPolicy_t *)(&dropPolicy));		
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setQueueDropWqValue: ponMacSetDropPolicy fail!\n");
			return ret;
		}
		#endif
	}
	
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d]: return 0,queueDropWq=%d\n",__FILE__, __LINE__,pq_ptr->queueDropWq);
	return ret;
}

int getDropPrecedenceColorMarkValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	uint16_t meId= 0;
	int ret = OMCI_GET_NO_VALUE;
	omci_priority_queue_ptr pq_ptr = NULL;
	
	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}
	
	pq_ptr = (omci_priority_queue_ptr)(me_info->attributes);
	meId = pq_ptr->meId;

	if(meId < T_CONT_INST_START_ID)
	{
		uint8_t queueId = 0;
		uint8_t dropPrecdenceColourMarking = 0;
		dropPolicy_t dropPolicy={0};
		uint32_t relatePort = 0;
		uint8_t port = 0;	
		//downstream priority queue
		/*wait for switch api*/ 
		relatePort = pq_ptr->relatedPort;
		port = (uint8_t)((relatePort >> 16) & 0x00ff);	
		queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_UIN_PORT); 													
		ret =  macMT7530GetDropPolicy(port, queueId, (mt7530_switch_DropPolicy_t *)(&dropPolicy));

		dropPrecdenceColourMarking = dropPolicy.DropPrecdenceColourMarking;
		pq_ptr->dropPrecedenceColourMarking = dropPrecdenceColourMarking;
	}
	else
	{
		//upstream priority queue
		//wait for pon mac api
#if 0
		queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_TCONT);												
		ret =  ponMacGetDropPolicy(port, queueId, &dropPolicy);
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"getDropPrecedenceColorMarkValue: ponMacGetDropPolicy fail!\n");
			return ret;
		}

		dropPrecdenceColourMarking = dropPolicy.dropPrecdenceColourMarking;
		pq_ptr->dropPrecedenceColourMarking = dropPrecdenceColourMarking;
#endif					
	}
	if(ret != 0)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"getDropPrecedenceColorMarkValue: macMT7530GetDropPolicy fail!\n");
		if(bbf247_enable)
		{
			return 0;
		}
		else
		{
			return -1;
		}
	}
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d]: return ret=%d,dropPrecedenceColourMarking=%d\n",__FILE__, __LINE__,ret,pq_ptr->dropPrecedenceColourMarking);
	return ret;
}
int setDropPrecedenceColorMarkValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	uint16_t meId= 0;
	int ret = 0;
	omci_priority_queue_ptr pq_ptr = NULL;
    uint8_t pcp_mode = 0;
	int direction = 0;

	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}
	
	pq_ptr = (omci_priority_queue_ptr)(me_info->attributes);
	meId = pq_ptr->meId;

	if(meId < T_CONT_INST_START_ID)
	{
		//downstream priority queue
		/*wait for switch api */
		uint8_t queueId = 0;
		uint8_t dropPrecdenceColourMarking = 0;
		dropPolicy_t dropPolicy={0};
		uint32_t relatePort = 0;
		uint8_t port = 0;	
		//downstream priority queue
		/*wait for switch api*/
		
		direction = DIR_DOWN;
		relatePort = pq_ptr->relatedPort;
		port = (uint8_t)((relatePort >> 16) & 0x00ff);	
		queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_UIN_PORT); 													
		ret =  macMT7530GetDropPolicy(port, queueId, (mt7530_switch_DropPolicy_t *)(&dropPolicy));
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setDropPrecedenceColorMarkValue: macMT7530GetDropPolicy fail!\n");
			return ret;
		}

		dropPrecdenceColourMarking = pq_ptr->dropPrecedenceColourMarking;
		dropPolicy.DropPrecdenceColourMarking= dropPrecdenceColourMarking;
		ret = macMT7530SetDropPolicy(port, queueId, (mt7530_switch_DropPolicy_t *)(&dropPolicy));		
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setDropPrecedenceColorMarkValue: macMT7530SetDropPolicy fail!\n");
			return ret;
		}
	}
	else
	{
		//upstream priority queue
		//wait for pon mac api
		direction = DIR_UP;
#if 0
		queueId = (uint8_t)((meId & 0x00ff)%NUM_OF_QUEUE_PER_TCONT);		
		ret = ponMacGetDropPolicy(port, queueId, &dropPolicy);
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setDropPrecedenceColorMarkValue: ponMacGetDropPolicy fail!\n");
			return ret;
		}
		
		dropPrecdenceColourMarking = pq_ptr->dropPrecedenceColourMarking;
		dropPolicy.DropPrecdenceColourMarking= dropPrecdenceColourMarking;
		ret = ponMacSetDropPolicy(port, queueId, &dropPolicy);		
		if(ret != 0)
		{
			omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setDropPrecedenceColorMarkValue: ponMacSetDropPolicy fail!\n");
			return ret;
		}
#endif					
	}

	pcp_mode = pq_ptr->dropPrecedenceColourMarking;
	omci_set_drop_preceduce_dei(pcp_mode >= 2 && pcp_mode < 7,direction); //pcpMode work together with dei
	if(pcp_mode > 2 && pcp_mode < 7)
		pcp_mode = 1 << (pcp_mode - 3);
	else
		pcp_mode = 0;
	omci_set_gdm_pcp_mode(pcp_mode,direction);
	
	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d]: return 0,dropPrecedenceColourMarking=%d\n",__FILE__, __LINE__,pq_ptr->dropPrecedenceColourMarking);
	return ret;
}
int setTcontPointValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	uint16_t qosCfg = 0;
	omci_traffic_scheduler_ptr traffic_sch_ptr = NULL;
	omci_me_info_t me_info_buf={0};
	omci_onu2_g_ptr onu2_g_ptr = NULL;
	
	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}
	traffic_sch_ptr = (omci_traffic_scheduler_ptr)(me_info->attributes);

	me_info_buf.class_id = OMCI_CLASS_ID_ONU2_G;
	me_info_buf.inst_id = 0;
	if(omci_attr_get_all_data_except_table_attr(&me_info_buf) != 0){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: get attribute fail.\n",__FILE__, __LINE__);
		return -1;
	}
	
	onu2_g_ptr = (omci_onu2_g_ptr)(me_info_buf.attributes);
	qosCfg = onu2_g_ptr->qosCfgFlexibility;
	if((qosCfg & 0x0004) == 0)
	{
		return OMCI_PARAM_ERROR;
	}

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d]: return 0,tcontPointer=%d\n",__FILE__, __LINE__,traffic_sch_ptr->tcontPointer);
	return 0;
}
int setTcontPolicyValue(omci_me_info_ptr me_info, omci_attr_dscp_ptr omci_attr)
{
	uint16_t qosCfg = 0;;
	int ret=0;
	omci_traffic_scheduler_ptr traffic_sch_ptr = NULL;
	omci_me_info_t me_info_buf={0};
	omci_onu2_g_ptr onu2_g_ptr = NULL;
	omci_me_info_t me_info_tcont_buf={0};
	omci_t_cont_ptr tcont_ptr = NULL;
	
	if(me_info == NULL ||	me_info->attributes ==NULL || omci_attr == NULL){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s] parameter is NULL, fail\n",__FUNCTION__);
		return -1;
	}
	traffic_sch_ptr = (omci_traffic_scheduler_ptr)(me_info->attributes);

	me_info_buf.class_id = OMCI_CLASS_ID_ONU2_G;
	me_info_buf.inst_id = 0;
	if(omci_attr_get_all_data_except_table_attr(&me_info_buf) != 0){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: get attribute fail.\n",__FILE__, __LINE__);
		return -1;
	}
	
	onu2_g_ptr = (omci_onu2_g_ptr)(me_info_buf.attributes);
	qosCfg = onu2_g_ptr->qosCfgFlexibility;
	if((qosCfg & 0x0008) == 0)
	{
		return OMCI_PARAM_ERROR;
	}

	/* PON MAC QOS Policy set*/
	me_info_tcont_buf.class_id = OMCI_CLASS_ID_T_CONT;
	me_info_tcont_buf.inst_id = traffic_sch_ptr->tcontPointer;
	if(omci_attr_get_all_data_except_table_attr(&me_info_tcont_buf) != 0){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR, "[%s][%d]: get attribute fail.\n",__FILE__, __LINE__);
		return -1;
	}

	tcont_ptr = (omci_t_cont_ptr)(me_info_tcont_buf.attributes);

	ret=setQOSPolicy(tcont_ptr->allocId,traffic_sch_ptr->policy);
	if(ret != 0)
		omcidbgPrintf(OMCI_DEBUG_LEVEL_ERROR,"setTcontPolicyValue: fail\n");

	omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE,"[%s][%d]: return 0,policy=%d\n",__FILE__, __LINE__,traffic_sch_ptr->policy);
	return 0;
}


int omci_me_traffic_desc_set_op(management_entry_ptr me_entry, omci_me_info_ptr me_info)
{
	int ret=0;
	omci_traffic_descriptor_ptr td_ptr=NULL;
	omci_gem_port_ctp_ptr gem_ctp_ptr=NULL;
	omci_onu_g_ptr  onu_g_ptr=NULL;
	omci_me_info_t me_info_buf={0};

	if(me_info==NULL || me_info->attributes == NULL)
	{
		omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d] input paramter pointer is NULL\n",__FUNCTION__,__LINE__);
		return -1;
	}
	td_ptr = (omci_traffic_descriptor_ptr)me_info->attributes;
	
	ret = omci_me_general_set_op(me_entry,me_info);
	if(ret != OMCI_CMD_SUCCESS)
	{	
		omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d] return ret=%d\n",__FUNCTION__,__LINE__,ret);
		return ret;
	}
	
	me_info_buf.class_id = OMCI_CLASS_ID_ONU_G;
	me_info_buf.inst_id = 0;
	if(omci_attr_get_all_data_except_table_attr(&me_info_buf) != 0){
		omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d] get attribute data fail\n",__FUNCTION__,__LINE__);
		return -1;
	}
	onu_g_ptr = (omci_onu_g_ptr)(me_info_buf.attributes);

	if( TCSUPPORT_PON_ROSTELECOM_VAL){	
		//traffic  management option
		if ( (0 != onu_g_ptr->trafficMgrOp) && (2 != onu_g_ptr->trafficMgrOp))
		{
			ret = OMCI_ATTR_FAIL_OR_UNKNOW;
		}
		
		//1-CIR 2-PIR 3-CBS 4-PBS
		if(me_info->mask& ((1<<(16-1)) | (1<<(16-2)) | (1<<(16-3)) | (1<<(16-4))))
		{
			//find gem ctp 
			me_info_buf.class_id = OMCI_CLASS_ID_GEM_PORT_CTP;
			me_info_buf.inst_id = td_ptr->meId; // implicit association
			if(omci_attr_get_all_data_except_table_attr(&me_info_buf) != 0){
				omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "[%s][%d] get attribute data fail\n",__FUNCTION__,__LINE__);
				return -1;
			}			
			gem_ctp_ptr = (omci_gem_port_ctp_ptr)me_info->attributes;
			omcidbgPrintf(OMCI_DEBUG_LEVEL_TRACE, "FILE = %s, LINE = %d\n",__FILE__, __LINE__);

			ret = omciAddQueueMappingRule(gem_ctp_ptr);
		}
	}

	return ret;
}

